728x90
Generic
- 요구 사항에 따라 모든 타입에서 동작하는 유연하고, 재사용 가능한 함수 및 타입을 작성 가능
- 제네릭이 해결하는 문제
- 특정 타입에 의존하지 않고, 모든 타입에서 작동하는 범용적인 코드 작성 가능
- 예를 들어, swapTwoInts라는 메소드는 Int라는 타입에 의존적임
- 제네릭을 사용하면 타입 매개변수가 호출 시점에 지정한 타입으로 변환됨
- 함수의 매개변수로 Int, String과 같은 타입이 아닌 타입 매개변수를 사용함
- 타입 매개변수는 함수의 전달 값의 타입에서 추론됨
- 프로토콜 정의
- 프로토콜을 정의할 때 제네릭을 사용하고 싶다면 associatedtype 사용
- 채택하는 측에선 typealias
Protocol
- 프로토콜은 타입
- 특정작업 또는 기능에 적합한 메소드, 속성을 정의하는 방법
- 클래스, 구조체, 열거형에 의해 채택되어 요구 사항의 실제 구현을 제공
- 프로토콜의 요구 사항을 충족하는 타입은 해당 프로토콜을 준수한다고 함
- 프로토콜은 타입이기 때문에 다른 타입(Int, String, ...)과 같이 대문자로 시작
- 인스턴스 속성 또는 타입 속성을 제공하기 위해 준수 타입 요구
- stored 속성, computed 속성인지 지정하지 않고, 속성 이름과 타입만 지정
- 대신 gettable, settable을 지정
- 프로토콜을 타입으로 사용하는 방법
- 프로토콜은 실제 기능을 구현하지 않지만, 다른 타입들이 프로토콜을 따르게 할 수 있다.
- 이로 인해 프로토콜을 타입처럼 사용할 수 있음
- Generic 제약으로 사용
- 특정 프로토콜을 준수하는 모든 타입에 대해 동작
- 호출자가 사용할 타입을 결정
- 불투명(Opaque) 타입으로 사용
- 구체적인 타입은 숨기고, 프로토콜 준수 여부만 보장
- API 구현이 타입을 결정하고, 추상화 계층을 유지
- 박스형(Boxed) 프로토콜 타입으로 사용
- 런타임에서 동적으로 다양한 타입과 동작
- 오버헤드가 발생하지만 유연성을 제공
- 프로토콜은 실제 기능을 구현하지 않지만, 다른 타입들이 프로토콜을 따르게 할 수 있다.
- 프로토콜 클래스로 제한
- AnyObject 프로토콜을 프로토콜의 상속으로 추가하면 프로토콜을 상속받는 타입을 클래스 타입으로 제한할 수 있음
- extension generic 제약
- where를 통해 메소드가 속성을 사용하기 위한 조건을 지정할 수 있음
Opaque Type, Boxed Protocol Type
- 값 타입에 대한 세부 구현 정보를 추상화하는 방법
- Swift는 값 타입에 대한 세부 정보를 숨기는 방법을 두 가지 제공
- 불투명 타입(opaque type), 박스형 프로토콜 타입(boxed protocol type)
- 반환 값의 타입이 비공개로 유지될 수 있기 때문에 유용
- 모듈과 모듈을 호출하는 코드의 경계에서 타입 정보를 숨길 수 있음
- 불투명 타입
- 반환 값의 타입을 숨김
- 메서드의 반환 타입으로 구체적인 유형을 제공하지 않고, 프로토콜의 관점에서 설명
- 타입 identity를 보존
- 컴파일러는 타입 정보에 액세스할 수 있지만, 모듈의 클라이언트는 그렇지 않다.
- 박스형 프로토콜 타입
- 주어진 프로토콜을 준수하는 모든 타입의 인스턴스를 저장할 수 있음
- 타입 identity를 보존하지 않음
- 값의 특정 타입은 런타임까지 알려지지 않는다.
- 다른 값이 저장됨에 따라 시간이 지나면 변할 수 있다.
- 값의 특정 타입은 런타임까지 알려지지 않는다.
- 불투명 타입이 해결하는 문제
- 메서드가 특정 타입을 반환하면서도, 구체적인 타입을 외부에서 알 수 없도록 숨길 수 있음
- 추상화 수준을 높이고, 구현 세부 사항을 감춘다.
- 모듈의 내부 구조를 노출하지 않으며 원하는 결과 제공
- 제네릭으로 구현하면 구체적인 타입이 드러나는 문제가 있다.
- 내부 타입은 모듈 사용자가 알 필요 없음
- 모듈의 세부 구현이 외부로 노출되는 문제 발생
- some 키워드 사용
- some Type을 반환해 구체적인 타입을 숨기며 Type 프로토콜을 준수한다고 보장
- 제네릭 vs 불투명
- 제네릭 타입: 호출자가 구체적인 타입 지정
- 불투명 타입: 함수 구현에서 구체적인 타입 지정, 외부에 숨김
- 제네릭 with 불투명
- 불투명 타입과 제네릭 타입을 결합하여 사용 가능
- 불투명 타입을 반환하지만, 내부적으로 제네릭으로 구현해 유연한 사용 가능
- 불투명 타입과 제네릭 타입을 결합하여 사용 가능
- 여러 반환 타입 불가
- 불투명 타입을 반환할 때는 반환 타입이 하나로 고정되어야 함
- 여러 타입을 반환할 경우 Swift는 불투명 타입을 사용할 수 없음
- 메서드가 특정 타입을 반환하면서도, 구체적인 타입을 외부에서 알 수 없도록 숨길 수 있음
- 박스형 프로토콜 타입이 해결하는 문제
- any 키워드 사용
- 프로토콜을 준수하는 여러 타입의 값을 하나의 컬렉션이나 변수에 저장할 수 있게 함
- boxed란 런타임에 타입이 결정되며 Swift가 필요할 때마다 간접 참조로 실제 타입을 관리하는 것
- 이로 인해 오버헤드 발생 가능
- 각 요소는 특정 프로토콜을 준수하지만 구체적으로 어떤 타입이던 혼합하여 저장 가능
- 장단점
- 장점
- 서로 다른 타입의 값을 한 변수에 저장할 수 있어 유연성 제공
- 특정 프로토콜을 준수하므로, 프로토콜의 메서드와 속성 사용 가능
- 단점
- 프로토콜에 정의되지 않은 메서드나 속성 접근 불가
- 프로토콜을 인자로 받아야 하는 함수에 중첩 사용 불가
- 장점
- 박스형 프로토콜 vs 불투명
- 박스형 프로토콜
- 여러 타입 허용
- 런타임에 동적으로 타입 결정
- 반환 타입 고정으로 타입 일관성 보장
- 불투명
- 단일 타입 반환
- 구체적인 타입 숨김
- 컴파일 시점에 타입 결정
- 다른 타입 반환으로 유연성 높지만 일관성 떨어짐
- 박스형 프로토콜
728x90
'Swift > Basic' 카테고리의 다른 글
프로젝트가 프로세스가 되기까지 - 2 (0) | 2024.12.18 |
---|---|
프로젝트가 프로세스가 되기까지 - 1 (1) | 2024.12.06 |
Data Type (0) | 2024.11.07 |
Concurrency (0) | 2024.11.07 |
GCD (0) | 2024.10.31 |