관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift 공식 문서] 23. Opaque result Type (불투명 반환 타입 some) 본문

swift 공식 문서

[iOS - swift 공식 문서] 23. Opaque result Type (불투명 반환 타입 some)

jake-kim 2021. 7. 23. 22:08

Opaque Type

  • Method가 있을 때 외부에서는 protocol을 준수한 구현체의 반환타입을 모르게끔 설정하는 방법
  • 함수의 반환 타입으로 고정 (concrete) 타입 을 제공하는 대신, 반환 값을 자신이 지원하는 프로토콜로 설명
  • 프로토콜 타입인 값을 반환하는 것과는 달리, 불투명 타입은 타입 정체성 (type identity) 을 보존
  • 반환 타입 앞에 some 키워드 기입

ex) some을 사용하지 않으면 컴파일 에러 발생되는 케이스1

// Error: Protocol 'Collection' can only be used as a generic constraint because it has Self or associated type requirements
func someList() -> Collection { 
    return [1, 2, 3]
}

func someList() -> some Collection { 
    return [1, 2, 3]
}

ex) some을 사용하지 않으면 컴파일 에러 발생되는 케이스2

protocol C: Equatable {
}

class A: C {

    static func == (lhs: A, rhs: A) -> Bool {
        return true
    }

}

// Protocol 'C' can only be used as a generic constraint because it has Self or associated type requirements
func getObject1() -> C {
    return A()
}

func getObject1() -> some C {
    return A()
}

Generics와 Opaque Type 구분

  • generics는 함수를 호출하는 코드가 타입을 결정
  • opaque는 함수 구현부에서 결정

ex) makeTrapezoid()는 반환타입을 호출하는 쪽에 노출하지 않으면서 실제 타입을 반환

struct Square: Shape {
  var size: Int
  func draw() -> String {
    let line = String(repeating: "*", count: size)
    let result = Array<String>(repeating: line, count: size)
    return result.joined(separator: "\n")
  }
}

func makeTrapezoid() -> some Shape {
  let top = Triangle(size: 2)
  let middle = Square(size: 2)
  let bottom = FlippedShape(shape: top)
  let trapezoid = JoinedShape(top: top, bottom: JoinedShape(top: middle, bottom: bottom))
  return trapezoid
}

let trapezoid = makeTrapezoid()
print(trapezoid.draw())

// *
// **
// **
// **
// **
// *

Protocol과 Opaque 반환 타입의 차이

  • Protocol은 타입 정체성을 가지고 있지 않지만, Opaque 타입은 비록 호출하는 쪽에는 어느 타입인지 알 수 없어도 하나이 특정한 타입을 참조
  • Protocol 타입은 프로토콜을 준수하는 어떤 타입이든 참조가 가능 - 유연성
  • Opaque 타입은 실제 타입들을 강하게 보증 - 제한성

* 참고

https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html

Comments