스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
매개변수 팩으로 API 범용화하기
Swift 매개변수 팩은 제네릭 코드의 가능성을 확장하는 강력한 도구이며 흔한 제네릭 패턴을 단순화할 수 있게 합니다. 제네릭 코드에서 인수의 개수뿐만 아니라 유형을 추상화하는 방법과 흔한 제네릭 패턴을 단순화하여 다중 정의를 피하는 법을 알려드리겠습니다. 이 세션을 최대한 유용하게 활용하려면 WWDC22의 'Swift 제네릭 받아들이기'를 먼저 확인하시기 바랍니다.
챕터
- 0:00 - Introduction
- 0:52 - What parameter packs solve
- 4:08 - How to read parameter packs
- 12:06 - Using parameter packs
- 17:22 - Wrap up
리소스
관련 비디오
WWDC23
WWDC22
-
다운로드
♪ ♪
'매개변수 팩으로 API 범용화하기' 세션에 오신 걸 환영합니다 저는 Swift 컴파일러 팀의 소피아라고 합니다 오늘은 Swift 매개변수 팩을 설명하고 이게 어떻게 제네릭 프로그래밍에 차원이 다른 유연성을 부여하는지 설명하겠습니다
이 강의는 기존 제네릭 시스템을 바탕으로 한 고급 강의입니다 이 주제를 잘 모르신다면 WWDC22의 'Swift 제네릭 받아들이기' 세션을 보시기를 권합니다 오늘 저는 매개변수 팩이 어떤 유형의 문제를 해결할 수 있으며 라이브러리에서 마주치는 매개변수 팩을 어떻게 생각해야 할지 알려드리겠습니다 마지막으로는 매개변수 팩을 활용해 여러분만의 코드를 구현하는 법을 자세히 설명하겠습니다 매개변수 팩에 관해 설명하기 전에 이게 왜 존재하는지를 이해하는 게 중요하므로 먼저 제네릭을 약간 설명한 다음 가변 매개변수를 살펴보겠습니다 코드는 기본적으로 두 가지 범주로 구성되는데 바로 값과 유형입니다 값을 추상화하려면 서로 다른 값을 매개변수로 받아들이는 함수를 작성하면 됩니다 예컨대 radians(from:) 함수에 각도를 나타내는 Double값을 무엇이든 입력하면 라디안을 나타내는 Double값이 새로 출력됩니다 유형을 추상화하려면 다양한 유형을 매개변수로 받아들이는 제네릭 코드를 작성하면 됩니다 예를 들어 표준 라이브러리 어레이 유형은 어떤 형태의 데이터로도 채울 수 있게 설계됐는데 여기에 있는 엘리먼트 유형 매개변수는 플레이스홀더로서 주어진 어레이 인스턴스에 사용할 고정 유형의 자리에 놓입니다 두 경우 모두 고정값 또는 고정 유형은 추상화할 때 인수로서 전달됩니다 제네릭 코드 대다수는 유형과 값을 모두 추상화합니다 이 점을 알아보기 위해 코드를 작성해서 서버에 쿼리를 보내도록 하겠습니다
기본으로 구현된 코드는 모종의 페이로드 유형을 요청받고 그 요청을 서버에 쿼리로 전달한 다음 최종적으로 페이로드 유형의 서버 응답을 반환할 것입니다 이 함수의 매개변수는 하나뿐이지만 전 한 호출에 여러 요청을 쿼리하도록 지원하고 싶습니다 인수의 개수가 가변적일 수 있게 하는 것은 가변 매개변수입니다 가변 매개변수는 함수가 단일 유형에서 인수를 몇 개라도 유연하게 받아들일 수 있게 합니다 하지만 가변 매개변수에는 한계가 있습니다 예컨대, 주어진 인수를 매핑해 인수의 개수와 길이가 동일한 투플을 만들고 싶다고 합시다 하지만 가변 매개변수를 쓰면 인수의 길이를 근거로 반환 유형을 선언할 방법이 없습니다 또한 가변 매개변수는 유형 소거를 사용하지 않는 한 다양한 유형을 받아들이지 못하므로 각 변수의 구체적인 정적 유형의 정보를 보존하지도 못합니다 제네릭 시스템과 가변 매개변수는 유형 정보를 보존하거나 인수의 개수를 달리하지 못합니다 현재로서는 이렇게 하려면 다중 정의를 쓸 수밖에 없는데 그러면 지원하는 인수 개수의 상한을 설정해야만 합니다 매개변수 두 개로 충분할까요? 아마 아닐 겁니다 매개변수를 세 개까지 처리하는 게 낫겠죠 그런데 네 개를 쓰고 싶다면 어쩌죠? 이런 다중 정의 패턴과 이 패턴의 한계는 개수가 여럿인 유형 매개변수를 처리하는 API 전반에 걸쳐 나타납니다 이 방법에는 중복이라는 단점도 있지만 더 중요한 단점은 인수를 몇 개까지 지원할지 상한을 임의로 설정해야 한다는 데 있습니다 선택한 상한을 초과하면 인수가 너무 많다는 컴파일러 오류가 발생합니다 매개변수 팩은 바로 이런 문제를 해결합니다 이런 다중 정의 패턴에 빠져드는 것은 매개변수 팩을 쓰는 게 좋다는 강력한 신호입니다 Swift 5.9에서 제네릭 시스템은 인수 길이 추상화에 대해 일급 지원을 받습니다 '매개변수 팩'이라는 새 구조를 통해서요 이제 여러분이 API에서 매개변수 팩을 볼 때 그게 뭘 의미하는지 설명하겠습니다 대체로 코드에서는 단 하나의 유형이나 값만으로 작업하는데 매개변수 팩은 여러 개의 유형이나 값을 하나로 뭉쳐 인수로 만들어 함수에 전달합니다 유형 각각을 담은 팩은 유형 팩이라고 합니다 예를 들어 다음과 같이 세 유형을 담은 팩이 있겠죠 Bool, Int, String을 담은 팩입니다 값 각각을 담은 팩은 값 팩이라고 합니다 예를 들어 다음과 같이 세 값을 담은 팩이 있겠죠 true, 숫자 10 빈 문자열을 담은 팩입니다 유형 팩과 값 팩은 함께 쓰입니다 유형 팩은 값 팩 안에 있는 값 각각에 유형을 하나씩 대응시킵니다 서로 대응하는 유형과 값은 각자의 팩 안에서 동일한 위치에 있죠 위치 0에서 true값의 유형은 Bool이고 위치 1에서 정수 리터럴 10의 유형은 Int이고 위치 2에서 빈 문자열 리터럴의 유형은 String입니다 매개변수 팩을 이용하면 단 하나의 제네릭 코드만 작성해도 코드가 팩에 든 모든 엘리먼트 각각에 작동합니다 이 개념이 낯설지 않으실 겁니다 Swift에서 컬렉션을 사용해 다양한 엘리먼트에 각각 작동하는 단 하나의 코드를 작성하는 데 익숙하실 테니까요 이런 코드는 반복을 통해 작성합니다 예를 들면 for-in 루프의 본문은 어레이의 각 엘리먼트에 작동합니다 매개변수 팩이 컬렉션과 다른 점은 팩에 든 각 엘리먼트에는 각자 다른 정적 유형이 있고 유형 레벨에서 팩을 대상으로 작업할 수 있다는 겁니다 일반적으로 다양한 고정 유형에 작용하는 제네릭 코드를 작성할 때는 꺾쇠괄호 안에 유형 매개변수를 선언하는데 Swift 5.9에서는 유형 매개변수 팩을 선언할 수 있습니다 'each'라는 키워드를 써서요 그러면 함수는 유형 매개변수를 단 하나만 갖는 대신 여러분이 쿼리하려는 각 페이로드 유형을 받아들입니다 이것을 유형 매개변수 팩이라고 합니다 유형 팩과 값 팩의 이름이 자연스럽게 읽히게 하려면 명명 규칙은 단수로 하세요 'each Payloads'라고 쓰지 않고 'each Payload'라고 하는 식으로요 매개변수 팩을 사용하는 제네릭 코드는 반복 패턴을 사용함으로써 각 페이로드에 작용할 수 있습니다 반복 패턴은 'repeat'라는 키워드로 표현되며 여기에 뒤이어 패턴 유형이라는 유형이 나옵니다 이 패턴에는 팩 엘리먼트 참조가 하나 또는 둘 이상 들어갑니다 'repeat'는 주어진 인수 팩의 각 엘리먼트에 패턴 유형이 반복될 것임을 가리킵니다 'each'는 플레이스홀더 노릇을 하며 반복이 일어날 때마다 팩에 든 각 엘리먼트로 대체됩니다 Bool, Int, String이 들어 있는 고정 유형 팩에서 대체가 어떤 식으로 일어나는지 봅시다 패턴은 세 번 반복되고 'each Payload' 플레이스홀더는 반복이 일어날 때마다 팩에 든 고정 유형으로 대체됩니다 그 결과, 쉼표로 구분된 유형 목록이 생성됩니다 Bool 요청, Int 요청, String 요청 이렇게요 반복 패턴은 쉼표로 구분된 유형 목록을 생성하므로 쉼표로 구분된 목록을 자연스럽게 받아들이는 위치에서만 쓸 수 있습니다 여기에는 괄호로 둘러싸인 유형도 포함되는데 이런 유형은 투플 유형 혹은 단일 유형입니다 쉼표로 구분된 목록은 함수 매개변수 목록에서도 쓸 수 있고 반복 패턴은 제네릭 인수 목록에서도 쓸 수 있습니다 반복 패턴을 함수 매개변수의 유형으로 사용하면 그 함수 매개변수는 값 매개변수 팩이 됩니다 그러면 호출자는 요청 인스턴스의 개수를 임의로 보낼 수 있게 되고 인수값은 팩으로 묶여 함수에 전달됩니다 이상으로 매개변수 팩의 기본 개념과 사용되는 구문을 설명했습니다 이번에는 이러한 원리가 API의 기능성을 단순화할 뿐만 아니라 확장한다는 걸 보여드릴 테니 쿼리 API로 돌아갑시다 저는 제네릭 다중 정의를 여러 개 추가했습니다 가변 요청 인수 및 그에 대응하는 반환 유형을 제시하기 위해서죠 각 다중 정의의 선언은 예측 가능한 패턴을 따릅니다 다중 정의에는 각각 한 개, 두 개, 세 개 네 개의 유형 매개변수가 있습니다 각 다중 정의는 유형 매개변수 각각을 매개변수 목록의 해당 유형에 대한 요청에 매핑하고 각 다중 정의에는 반환 유형에 있는 유형 매개변수 각각의 목록이 들어 있습니다 매개변수 팩을 사용하면 이 네 개의 다중 정의를 단 하나의 함수로 줄일 수 있습니다 먼저 유형 매개변수 선언을 검토하고 그다음 함수 매개변수 목록을 마지막엔 반환 유형을 검토합시다 각각의 유형 매개변수를 줄여서 유형 매개변수 팩으로 만들 수 있고 각각의 요청 매개변수를 줄여서 값 매개변수 팩을 만들 수 있고 반환 유형은 줄여서 각 페이로드 유형을 반복해 구성한 투플로 만들 수 있습니다 그러면 요청 인수가 몇 개든 처리할 수 있는 쿼리 함수 하나만이 남죠 함수 매개변수와 종속 유형은 둘 다 'each Payload'라는 유형 매개변수 팩의 종속 유형이므로 함수의 값 매개변수 팩의 길이는 반환되는 투플에 들어 있는 엘리먼트의 개수와 반드시 일치한다는 걸 알 수 있습니다 제가 이 API에 매개변수 팩을 도입했으니 이 단일한 쿼리 함수를 인수 하나로 호출해도 되고 셋으로 호출해도 되고 몇 개로 호출해도 됩니다 매개변수 팩은 모든 인수 길이를 똑같이 처리하니까요 인수 셋을 사용한 호출을 살펴봅시다 고정 인수 팩은 호출 사이트에 있는 인수로부터 추론된 것입니다 'each Payload' 플레이스홀더에 해당하는 고정 유형은 모두 인수 목록에서 수집되어 유형 팩으로 묶이고 고정 유형 팩이 대체되면서 반환 유형이 생성됩니다 'each Payload'는 매개변수 목록과 반환 유형에 나타납니다 고정 유형 팩인 Int, String, Bool이 두 곳에서 모두 대체됨에 따라 패턴이 세 번 반복됩니다 결국, 실행되는 코드는 유형 팩의 세 유형 모두를 반복한 것과 동일해집니다 이제 쿼리 API로 돌아가 매개변수 팩에 제약을 추가하는 법을 알아봅시다 우리의 쿼리 페이로드가 Equatable 해야 한다고 가정합시다 콜론과 Equatable 프로토콜 이름을 유형 매개변수 팩 뒤에 추가하면 페이로드 팩에 든 모든 엘리먼트는 Equatable을 준수해야만 합니다 더 일반적인 필요조건은 where 절로 선언할 수 있습니다 평범한 제네릭과 마찬가지로요 매개변수 팩에 든 인수가 0개 또는 그보다 많을 수 있다는 점을 기억하면 이 서버 쿼리 API에는 인수 0개를 받아들일 이유가 딱히 없다는 생각이 드실지도 모르겠습니다 다행히도 간단한 기법으로 최소한의 인수 개수를 정할 수 있습니다 이 경우에 저는 인수가 적어도 하나여야 한다고 정하고 싶군요 함수가 뭐라도 할 일이 생기게요 이렇게 정하려면 정규 유형 매개변수를 유형 매개변수 팩 앞에 추가하고 여기에 대응하는 값 매개변수를 값 매개변수 팩 앞에 추가합니다 그러면 유형 매개변수 팩에 가해진 제약이 새 유형 매개변수에도 적용되는데 이 경우엔 Equatable 준수가 제약에 해당하죠 이제 함수 호출자는 적어도 인수 하나를 제시해야 합니다 지금까지 우리는 기본적인 내용을 다뤘습니다 매개변수 팩이 어떤 문제를 해결하고 API에 있는 매개변수 팩을 어떻게 읽는지를 다뤘죠 다음으로는 매개변수 팩을 사용한 코드를 구현하는 법을 알아봅시다 매개변수 팩을 사용해 서버 쿼리 구현을 빌드하겠습니다 이 쿼리 함수가 받아들이는 값 팩의 모든 개별 엘리먼트는 유형 팩의 모든 엘리먼트에 대한 요청입니다 이 요청 구조체에는 페이로드라는 단 하나의 유형 매개변수가 있고 페이로드 인스턴스를 반환하는 평가 메서드 하나가 있습니다 쿼리 함수의 본문은 'item' 값 팩에 작동할 것입니다 쿼리의 본문 안에서 저는 값 팩의 각 item에 대한 평가 메서드를 호출하고 싶은데 이것은 반복 패턴을 사용해 표현할 수 있습니다 반복 패턴은 유형 레벨과 값 레벨에서 동일한 구문을 사용해 표현합니다 값 레벨에서는 패턴 표현이 'repeat' 키워드 다음에 나옵니다 패턴 표현에는 값 팩이 하나 또는 둘 이상 들어갑니다 팩은 팩에 든 모든 값을 통해 반복되며 표현은 값 하나당 한 번씩 평가됩니다 투플에 들어 있는 모든 평가 결과의 목록을 생성하려면 패턴 표현을 괄호로 감싸면 됩니다 함수로 전달된 값 팩이 비었다면 그 결과 빈 투플이 만들어지고 값 팩에 인수가 하나라면 단 하나의 값이 만들어지고 값 팩에 여러 엘리먼트가 있다면 투플이 만들어질 겁니다 이게 다입니다 이제 우리의 쿼리 함수는 결과물의 값 팩을 받아들이고 각각의 요청을 평가하고 모든 요청에 대한 결과를 투플로 한데 묶어 반환합니다 이게 바로 코드에 매개변수 팩을 활용하는 방법의 기본입니다 매개변수 팩이 아니라 다중 정의 여러 개를 사용한 이전의 예제보다 코드가 훨씬 짧아졌죠 심지어 이전 예제에는 구현조차 없었죠 유지 보수 하기도 쉬워졌고 코드 패턴이 반복되면서 흔히 생기는 오류도 없어졌습니다 이제 유연성을 좀 더 높여 봅시다 제 예제를 리팩터링해서 쿼리 API가 상태를 저장할 수 있게 하고 각 요청 상태의 입출력 유형이 서로 달라질 수 있게 하고 매개변수 팩이 반복되는 동안 제어 흐름을 관리하게 하겠습니다 쿼리 함수를 평가자 구조체 안으로 옮기고 유형 매개변수 팩을 쿼리 메서드에서 평가자 유형으로 옮기겠습니다 평가자 구조체는 요청 팩을 괄호로 감싸 투플값으로 만들어 저장 프로퍼티 안에 저장할 수 있습니다 고정된 페이로드 유형 인수 팩이 주어지면 'item' 변수는 단일한 요청이 되거나 모든 요청의 투플이 될 것입니다 그다음 저는 요청을 구조체에서 프로토콜로 바꿀 텐데 이 프로토콜에는 이름이 Output인 연관 유형이 있습니다 또한 요청 프로토콜에 Input이라는 연관 유형을 추가한 다음 요청의 평가 메서드를 업데이트하여 그 인수를 프로토콜의 Input 유형으로 만들겠습니다 이렇게 하면 메서드의 반환 유형이 인수의 유형과 달라질 수 있습니다 그런 뒤 평가자를 업데이트하여 모든 페이로드 유형이 반드시 요청을 준수하게 하고 저장 프로퍼티인 'item'도 그것에 맞게 업데이트해 단순하게 'each Payload'의 유형이 되게끔 합니다 그런데 이 시점에 이르면 'Payload'라는 이름은 평가자의 유형 매개변수 팩에 더는 어울리지 않습니다 이제 페이로드는 요청 안에 들어 있는 게 아니라 요청 전체를 준수하니까요 그러므로 페이로드의 이름을 요청으로 바꾸고 프로토콜의 이름을 RequestProtocol로 바꾸겠습니다 이제 쿼리 메서드는 각 요청의 Input 유형 팩을 받아들일 수 있고 각 요청의 Output 유형의 목록을 반환하게 됩니다 마지막으로, 쿼리 메서드에 대한 새 매개변수인 'input'을 모든 item의 평가 메서드에 대한 호출에 전달하기만 하면 됩니다 이제 우리가 쿼리 안에 포함하는 데이터 유형과 다른 유형을 서버에서 반환하게 할 수 있습니다 메서드의 값 인수 팩의 길이가 반환된 값 팩의 길이와 같다는 걸 아실 수 있습니다 두 팩의 유형 모두 평가자의 유형 팩에 기초하니까요 저장 프로퍼티인 'item'의 인수 길이도 마찬가지입니다 매개변수 팩을 사용하는 것은 반복의 한 형태이므로 반복을 일찍 종료하려 한다면 제어 흐름은 어떡해야 할지 궁금하실 수 있겠습니다 모든 쿼리가 성공한 경우에만 쿼리 컬렉션의 결과가 효력을 발휘해야 하는 경우가 있을 수도 있습니다 이 경우에는 던지는 오류를 쓸 수 있습니다 이 예제에서는 RequestProtocol의 평가 메서드를 업데이트해 던지는 함수로 만들고 평가자의 쿼리 메서드의 반환 유형을 수정하여 선택적인 유형으로 하면 됩니다 쿼리 메서드의 본문을 do-catch문 안으로 옮겨 반환문을 do 절 안에 넣고 catch 절에서 nil을 반환하게 하면 됩니다 이제 필요한 경우 개별 쿼리 평가를 통해 모든 쿼리의 반복을 중지할 수 있습니다 이 세션에서는 제네릭 코드에서 매개변수 팩을 이용해 인수의 개수만이 아니라 유형을 어떻게 추상화할 수 있는지 이야기했습니다 매개변수 팩을 사용해 코드를 단순화하고 코드의 한계를 제거하는 법도 살펴봤습니다 단 하나의 제네릭 구현만 작성하면 됐었죠 예전이라면 수많은 다중 정의가 필요했겠지만요 마지막으로는 매개변수 팩을 활용하면서 서버로 쿼리 전송을 구현하는 코드를 작성했습니다 제네릭을 더 자세히 알고 싶다면 WWDC22의 'Swift 제네릭 받아들이기' 세션을 보세요 프로토콜과 유형 소거를 더 자세히 알고 싶다면 WWDC22의 'Swift에서 프로토콜 인터페이스 디자인하기' 세션을 보세요 Swift 매개변수 팩은 제네릭 코드의 가능성을 확장하는 강력한 도구이며 흔한 제네릭 패턴을 단순화할 수 있도록 해 줍니다 매개변수 팩으로 빌드할 여러분의 작품을 기대하겠습니다 시청해 주셔서 감사합니다
-
-
1:13 - radians function
func radians(from degrees: Double) -> Double
-
1:26 - Array type
struct Array<Element>
-
1:48 - radians function and Array type with concrete expressions
func radians(from degrees: Double) -> Double radians(from: 180) struct Array<Element> Array<Int>
-
2:04 - generic query
func query<Payload>(_ item: Request<Payload>) -> Payload
-
2:22 - variadic query
func query(_ item: Request...)
-
3:16 - generic query
func query<Payload>(_ item: Request<Payload>) -> Payload
-
3:23 - two query overloads
func query<Payload>( _ item: Request<Payload> ) -> Payload func query<Payload1, Payload2>( _ item1: Request<Payload1>, _ item2: Request<Payload2> ) -> (Payload1, Payload2)
-
3:28 - three query overloads
func query<Payload>( _ item: Request<Payload> ) -> Payload func query<Payload1, Payload2>( _ item1: Request<Payload1>, _ item2: Request<Payload2> ) -> (Payload1, Payload2) func query<Payload1, Payload2, Payload3>( _ item1: Request<Payload1>, _ item2: Request<Payload2>, _ item3: Request<Payload3> ) -> (Payload1, Payload2, Payload3)
-
3:31 - four query overloads with extra argument error
func query<Payload>( _ item: Request<Payload> ) -> Payload func query<Payload1, Payload2>( _ item1: Request<Payload1>, _ item2: Request<Payload2> ) -> (Payload1, Payload2) func query<Payload1, Payload2, Payload3>( _ item1: Request<Payload1>, _ item2: Request<Payload2>, _ item3: Request<Payload3> ) -> (Payload1, Payload2, Payload3) func query<Payload1, Payload2, Payload3, Payload4>( _ item1: Request<Payload1>, _ item2: Request<Payload2>, _ item3: Request<Payload3>, _ item4: Request<Payload4> ) -> (Payload1, Payload2, Payload3, Payload4) let _ = query(r1, r2, r3, r4, r5)
-
5:52 - for-in loop over requests
for request in requests { evaluate(request) }
-
8:41 - four query overloads
func query<Payload>( _ item: Request<Payload> ) -> Payload func query<Payload1, Payload2>( _ item1: Request<Payload1>, _ item2: Request<Payload2> ) -> (Payload1, Payload2) func query<Payload1, Payload2, Payload3>( _ item1: Request<Payload1>, _ item2: Request<Payload2>, _ item3: Request<Payload3> ) -> (Payload1, Payload2, Payload3) func query<Payload1, Payload2, Payload3, Payload4>( _ item1: Request<Payload1>, _ item2: Request<Payload2>, _ item3: Request<Payload3>, _ item4: Request<Payload4> ) -> (Payload1, Payload2, Payload3, Payload4)
-
9:37 - parameter pack query interface
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload)
-
10:01 - parameter pack query with single argument call
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload) let result = query(Request<Int>())
-
10:08 - parameter pack query with single and triple argument calls
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload) let result = query(Request<Int>()) let results = query(Request<Int>(), Request<String>(), Request<Bool>())
-
10:15 - parameter pack query with triple argument call
func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload) let results = query(Request<Int>(), Request<String>(), Request<Bool>())
-
10:56 - parameter pack query interface
func query<each Payload>( _ item: repeat Request<each Payload> ) -> (repeat each Payload)
-
11:03 - parameter pack query interface with conformance
func query<each Payload: Equatable>( _ item: repeat Request<each Payload> ) -> (repeat each Payload)
-
11:17 - parameter pack query interface with where clause
func query<each Payload>( _ item: repeat Request<each Payload> ) -> (repeat each Payload) where repeat each Payload: Equatable
-
11:44 - parameter pack query interface with minimum parameter count
func query<FirstPayload, each Payload>( _ first: Request<FirstPayload>, _ item: repeat Request<each Payload> ) -> (FirstPayload, repeat each Payload) where FirstPayload: Equatable, repeat each Payload: Equatable
-
13:42 - parameter pack query implementation
struct Request<Payload> { func evaluate() -> Payload } func query<each Payload>(_ item: repeat Request<each Payload>) -> (repeat each Payload) { return (repeat (each item).evaluate()) }
-
16:04 - parameter pack query implementation with different input and output types
protocol RequestProtocol { associatedtype Input associatedtype Output func evaluate(_ input: Input) -> Output } struct Evaluator<each Request: RequestProtocol> { var item: (repeat each Request) func query(_ input: repeat (each Request).Input) -> (repeat (each Request).Output) { return (repeat (each item).evaluate(each input)) } }
-
17:05 - parameter pack query implementation with control flow break
protocol RequestProtocol { associatedtype Input associatedtype Output func evaluate(_ input: Input) throws -> Output } struct Evaluator<each Request: RequestProtocol> { var item: (repeat each Request) func query(_ input: repeat (each Request).Input) -> (repeat (each Request).Output)? { do { return (repeat try (each item).evaluate(each input)) } catch { return nil } } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.