이전 예제들에서 사용했던 swapTwoValues(:) 함수나 Stack 타입은 모든 타입과 함께 사용할 수 있습니다.
타입 제약을 조건을 이용해서 타입 파라미터가 특정 클래스에서 상속되거나 특정 프로토콜 또는 프로토콜 구성을 준수해야 하도록 제약을 줄 수 있습니다.
예를들어 Swift의 Dictionary 타입은 Dictionary의 키로 사용될 수 있는 타입에 재한을 둡니다.
바로 hasable 프로토콜을 준수해야 합니다. 이 요구사항이 만족되지 않으면 딕셔너리의 키로 사용될 수 없습니다.
Type Constraint Syntax (타입 제약 구문)
제네릭 함수에서 타입 제약에 대한 구문을 작성하는 방법은 아래와 같습니다.
위 에제의 함수는 2개의 타입 파라미터를 가집니다.
첫번째 파라미터 T는 SomeClass 의 서브 클래스이어야 하고, 두번째 파라미터 U는 SomeProtocol을 준수해야 한다는 타입 제약이 있습니다.
Type Constraints in Action (타입 제약 동작)
다음은 찾을 String값과 찾을 String 값의 배열이 주어진 findIndex(orString:in:) 이라는 제네릭이 아닌 함수입니다.
findIndex(orString:in:) 함수는 배열에서 일치하는 문자열을 찾으면 그 인덱스를 찾지 못하면 nil인 옵셔널 Int 값을 반환합니다.
findIndex(orString:in:) 함수는 배열의 문자열에서 문자열 값을 찾기 위해 사용됩니다:
배열에서 값의 인덱스를 찾는 원리는 문자열에만 유용하지 않습니다.
문자열에 대한 언급을 T 타입의 값으로 대체하여 제네릭 함수로 같은 기능을 구현할 수 있습니다.
다음은 findIndex(of:in) 이라는 findIndex(orString:in:) 의 제네릭 버전입니다.
이 함수는 배열의 옵셔널 값이 아닌 옵셔널 인덱스를 반환 하므로 반환 타입은 똑같이 Int? 입니다.
하지만 이 함수는 뒤에 설명할 이유로 인해서 컴파일 되지 않습니다.
위에 설명한 내용 왜 컴파일 되지 않을까요??
파라미터만 타입 파라미터로 바뀠고 옵셔널값을 반환하니 실패하면 nil을 반환하면 될텐데?
이유는 “if value == valurToFind “ 코드에 있습니다.
Swift의 모든 타입이 동등 연산자(==)를 이용해서 비교할 수 있지 않습니다.
예를들자면 복잡한 데이터 모델을 표현하기 위해서 클래스나 구조체가 사용된다면 같음의 의미는 Swift가 추측할 수 있는 것이 아닙니다.
이로 인해 이 코드가 가능한 모든 타입의 T 에 대해 작동한다고 보장할 수 없으면 코드를 컴파일 하려고 하면 에러가 발생합니다.
// Binary operator '==' cannot be applied to two 'T' operands
Swift 표준 라이브러리는 타입의 모든 2개의 값을 비교하기 위해서 동등 연산자 (==) 와 비동등 연산자 (!=)를 구현하기 위해서 Equatable 프로토콜을 정의하여 준수하도록 요구합니다.
Swift의 모든 표준 타입은 Equatable 프로토콜을 자동으로 지원합니다.
Equatable 인 모든 타입은 동등 연산자를 지원하기 때문에 findIndex(of:in:) 함수와 함께 안전하게 사용될 수 있습니다.
이것을 표현하기 위해서 함수를 정의할때 타입 파라미터의 정의 부분에 Equatable 의 타입 제약을 작성합니다.
findIndex(of:in:) 에 대한 단일 타입 파라미터는 “Equatable 프로토콜을 준수하는 T 타입의 모든 것” 이라는 의미로 T: Equatable 로 작성됩니다.
findIndex(of:in:) 함수는 이제 컴파일에 성공하고 Double, String 등과 같은 Equatable인 모든 타입에 대해 사용될 수 있습니다.
'Swift > 꼬꼬무' 카테고리의 다른 글
Generic Where Clauses (제네릭 where 절) (0) | 2023.08.07 |
---|---|
Associated Types (연관된 타입) (0) | 2023.08.07 |
Generics - Generic Types (0) | 2023.07.26 |
Generics - Type Parameters (0) | 2023.07.26 |
Generics - Generic Functions (0) | 2023.07.18 |