티스토리 뷰

Opaque Type

불투명 유형(opaque type)은 기본 구체적인 유형을 지정하지 않고 프로토콜 또는 프로토콜 구성을 준수하는 유형을 정의합니다.

불투명 유형은 함수 또는 서브크립트의 반환 타입 또는 프로퍼티의 타입으로 나타납니다.

불투명 유형은 튜플 유형 또는 제네릭 유형(배열의 요소 유형 또는 옵셔널 타입의 래핑된 유형과 같은)의 일부로 표시될 수 없습니다.

Opaque types have the following form:

some constraint

constraint은 class 유형, protocol 유형, protocol composition 유형 또는 Any입니다.

값은 listed 프로토콜 또는 프로토콜 구성을 준수하거나 listed 클래스에서 상속되는 형식의 인스턴스인 경우에만 불투명 형식의 인스턴스로 사용할 수 있습니다.

불투명 값과 상호 작용하는 코드는 constraint에 의해 정의된 인터페이스의 일부인 방식으로만 값을 사용할 수 있습니다.

프로토콜 선언은 불투명 유형을 포함할 수 없습니다.

클래스는 불투명 유형을 nonfinal 메서드의 반환 유형으로 사용할 수 없습니다.

불투명 형식을 반환 형식으로 사용하는 함수는 단일 기본 유형(underlying type)을 공유하는 값을 반환해야 합니다.

반환 유형은 함수의 제네릭 유형 파라미터의 부분을 포함할 수 있습니다.

예를 들어,someFunction<T>() T 또는 Dictionary<String, T> 타입의 값을 반환할 수 있습니다.

Metatype Type

메타타입 유형(metatype type)은 클래스 유형, 구조 유형, 열거 유형 및 프로토콜 유형을 포함한 모든 유형의 타입을 나타냅니다.

클래스, 구조체 또는 열거 유형의 메타 유형은 해당 유형의 이름 뒤에 .Type이 나옵니다.

런타임에 프로토콜을 준수해서 구체적인 유형이 아닌 프로토콜 유형의 메타타입은 해당 프로토콜의 이름 다음에 .Protocol이 나옵니다.

예를 들어, SomeClass 클래스 타입의 메타타입은 SomeClass .Type입니다

SomeProtocol 프로토콜의 메타타입은 SomeProtocol.Protocol입니다.

self 접미사를 사용해서 type을 값으로 접근할 수 있습니다.

예를 들어 SomeClass.self SomeClass의 인스턴스가 아니라 SomeClass 자신을 리턴합니다.

SomeProtocol.self SomeProtocol을 런타임에 준수하는 유형의 인스턴스가 아니라 SomeProtocol 자신을 리턴합니다.

다음 예에서 알 수 있듯이 유형의 인스턴스로 type(of:) 함수를 호출하여 해당 인스턴스의 동적 런타임 유형에 값으로 액세스할 수 있습니다.

class SomeBaseClass {
    class func printClassName() {
        print("SomeBaseClass")
    }
}
class SomeSubClass: SomeBaseClass {
    override class func printClassName() {
        print("SomeSubClass")
    }
}
let someInstance: SomeBaseClass = SomeSubClass()
// The compile-time type of someInstance is SomeBaseClass,
// and the runtime type of someInstance is SomeSubClass
type(of: someInstance).printClassName()
// Prints "SomeSubClass"

Initializer 식을 사용하여 해당 형식의 메타 형식 값으로 형식의 인스턴스를 구성합니다.

클래스 인스턴스의 경우 호출되는 이니셜라이저를 required 키워드로 표시하거나 전체 클래스를 final 키워드로 표시해야 합니다.

class AnotherSubClass: SomeBaseClass {
    let string: String
    required init(string: String) {
        self.string = string
    }
    override class func printClassName() {
        print("AnotherSubClass")
    }
}
let metatype: AnotherSubClass.Type = AnotherSubClass.self
let anotherInstance = metatype.init(string: "some string")

Self Type

Self 유형은 구체적인 유형이 아닙니다. 해당 유형의 이름을 알거나 반복하지 않고 현재 유형을 편리하게 지시할 수 있습니다.

프로토콜 선언 내에서 혹은 프로토콜 멤버 선언에서 Self 타입은 그 프로토콜을 준수하는 타입(eventual type)을 지시합니다.

구조체, 클래스, 열거형 선언에서 Self타입은 선언에서 소개한 타입을 지시합니다.

타입의 멤버를 위한 정의의 내부에서 Self는 그 타입을 지시합니다.

클래스 선언의 멤버의 경우 Self는 다음을 나타냅니다:

  • 메서드의 리턴 타입
  • 읽기 전용 서브스크립트의 리턴 타입
  • 읽기 전용 computed 프로퍼티의 타입
  • 메서드의 바디

예를 들어 리턴 타입이 Self인 인스턴스 메서드를 다음에서 보여줍니다.

class Superclass {
    func f() -> Self { return self }
}
let x = Superclass()
print(type(of: x.f()))
// Prints "Superclass"

class Subclass: Superclass { }
let y = Subclass()
print(type(of: y.f()))
// Prints "Subclass"

let z: Superclass = Subclass()
print(type(of: z.f()))
// Prints "Subclass"

z의 타입이 컴파일 타임에 Superclass가 아니라 런타임의 타입인 Subclass임을 마지막 예시에서 알 수 있습니다.

nested 타입 선언에서, Self는 가장 안쪽 타입을 가리킵니다.

Self타입은 type(of:) 함수의 타입꽈 같은 유형입니다.

Self.someStaticMember 을 써서 현재 타입의 멤버에 접근 하는 것은 type(of: self).someStaticMember와 동일합니다.

https://docs.swift.org/swift-book/ReferenceManual/Types.html#grammar_opaque-type

댓글
공지사항