Polymorphism
- 다른 구체 타입에 대해서 다르게 동작하는 추상화 기법.
- 코드가 어떻게 사용되냐에 따라 one piece of code가 많은 동작을 가질 수 있다.

동물을 추가해서 각각 먹이를 먹이게 되면, boilerplate 코드가 된다. 다른 동물 타입들의 feed 함수가 매우 비슷한 것을 볼 수 있음. → 통일 해보자

Polymorphism은 one piece of code가 다른 행동을 가능하게 한다.
- ad-hoc polymorphism
- argument type에 의존해 같은 Function call이지만 다른 것을 의미하게 할 수 있다.
- Overloading은 일반적인 솔루션이 아니기 때문에 “ad-hoc polymorphism”이라 부를 수 있음.
- subtype polymorphism

- supertype에서 작동하는 코드는 런타임에 코드가 사용하는 특정 하위 클래스에 대해 다른 동작을 가질 수 있다.
- 하지만 override와 type parameter를 사용해서 해결하는 방법은 좋지 못한 것 같다. override의 구현을 subclass에서 강제하지 못할 뿐더러 type parameter를 활용하는 방법 또한 동물이 음식을 먹는 것만이 핵심 목적이 아니기 때문이다.
- parametric polymorphism

Generic code는 type parameters를 사용해서 다른 types로 동작하는 one piece of code를 쓸 수 있게 되고, 구체 types이 하나의 매개변수로 사용되게 된다.
Protocol
- interface that represents capabilities
- separates ideas from implementation details
- abstraction tool that describes the functionality of conforming types
- separates ideas from implementation details
- each capability maps to a protocol requirement
- the name of the protocol should represent the category of types we're describing
associatedtype
- serves as a placeholder for a concrete type
- associated types depend on the specific type that conforms to the protocol
Opaque type vs. underlying type
- Opaque type(불투명 타입)
- 특정 구체 타입에 대한 placeholder를 대표하는 추상 타입
- abstract type that represents a placeholder for a specific concrete type
- Opaque type의 지역변수는 항상 초기값을 가져야 한다.

- underlying type
- opaque type으로 substituted된 특정 구체 타입
- specific concrete type that is substituted in the opaque type
- opaque type이 있는 값의 경우, 값의 scope에 대해 underlying type이 고정된다.
- 값을 사용하는 generic code는 값이 사용되는 각각의 시간마다 보장된 같은 underlying type을 얻을 수 있다.
- opaque type의 파라미터의 경우 underlying type은 호출 부분의 argument로 부터 유추된다.

- opaque type의 result type의 경우, underlying type이 구현의 반환값에 유추된다. 즉, underlying return type 이 모든 return 문에서 동일해야 함.
- SwiftUI에서는 이러한 문제를 ViewBuilder Annotation으로 해결한다.

- opaque type은 inputs, outputs 둘다 사용될 수 있다.
- opaque types in Swift
- some Animal, <T: Animal>
Writing generic interfaces
//Swift 5.6 and earlier:
func feed<A>(_ animal: A) where A: Animal
// Equivalents
func feed<A: Animal>(_ animal: A)
//Swift 5.7 and later:
func feed(_ animal: some Animal)
- 우리는 some xxx 을 통해서 protocol contormance의 관점에서 추상 타입을 표현할 수 있다.
- 위의 세가지 선언 방법은 모두 동일하지만 5.7 이후 some 표현은 훨신 이해하기 쉽다.
- some 키워드는 parameter, result type에 사용할 수 있다.
- some을 사용하면 특정 underlying type이 달라질 수 없게 된다.


이전 선언과 동일한 동작을 한다. 하지만 “some Animal”로 적는 것은 더 직관적이다. animal paramete에 대한 syntactic noise를 줄이고, semantic information을 증가시킨다.
any
- some으로 선언된 배열은 underlying type에 의해 특정 구체 타입으로 scope가 고정된다. 하지만 any를 사용하면 이러한 문제를 해결할 수 있다.

any Animal
- any Animal type은 모든 구체 Animal type을 담을 수 있게 되고, existential type이라고 부른다.
- 다른 구체 타입들에 대해 동일한 표현을 사용하는 방법을 type erasure라고 부른다. 구체 타입은 컴파일 타임에 erase 되고 런타임에 알려지게 된다.
- associated types가 있는 프로토콜에 any 키워드를 사용하는 것이 Swift 5.7의 새로운 기능.


- any Animal과 some Animal은 서로 다른 타입이지만, 컴파일러에서는 underlying value를 unboxing 하고, som Animal 파라미터로 직접 전달함으로서 any Animal의 인스턴스를 some Animal로 변환할 수 있다.
- some Animal 파라미터 범위의 경우, 값이 underlying type 으로 고정되있으므로 underlying type 에 대한 operations 를 포함하여 associated types 에도 액세스 가능.
- 이것은 정적 타입의 표현성을 갖는 컨텍스트로 돌아갈 수 있도록 해준다. 위의 some 을 사용한 파라미터를 통해서 각 동물을 feed 메서드로 전달할 수 있다. 이를 통해 각 반복에서 특정 동물에게 먹일 적절한 작물을 재배하고 수확하여 먹일 수 있다.
some과 any는 다른 capabilites를 가지고 있음.

some vs. any
- some
- 구체 타입(concrete type)을 고정시킴으로써 타입 관계들을 보장한다.
- any
- 임의 구체 타입(arbitrary concrete type)으로 타입 관계들을 erases 한다.
- some을 default로 사용하되, 임의의 값(arbitrary values)를 저장해야 하는 경우 any로 변경한다(arbitrary concrete types instances).
'Swift > 학습' 카테고리의 다른 글
| Existential any in Swift explained with code examples(번역) (0) | 2023.04.06 |
|---|---|
| Swift Opaque Types(번역) (0) | 2023.03.28 |
| enum으로 특정 단위를 명확하게 표현하기 (0) | 2022.09.25 |
| Swift Subscripts (0) | 2022.05.23 |
| Protocol Optional Function (0) | 2022.04.14 |