제일 먼저 swiftui로 app을 만들면 만나는 코드! 그런데 우리는 과연 이 코드를 정확히 이해하고 사용하는 것일까??
다른 사람은 모르겠지만 저는 일단 NOPE!!
Some
struct ContentView : View {
var body : Text {
Text("Hello World")}}
위의 코드는 에러를 표출하지 않고 정상 작동한다. 하지만 body에 text이외의 다른 타입이 들어가게 되면 에러가 뜬다.
이럴때 사용하는 것이 some View. 다양한 view 프로토콜을 준수하는 구조체들을 마음껏 사용할 수 있게 된다.
아주아주아주 중요한 키워드니까 꼭 기억해야 할것!
그렇다면 우리는 여기서 또 궁금증을 느끼게 된다. Opaque Type이 뭔데???
- 프로토콜과 달리 associated types과 함께 작업을 할수 잇다. 어차피 구현부를 통해 구체타입을 알게된다.
- 매번 내부적으로 동일한 타입을 사용! (이게 any와 차이점)
- 세부 구현 정보를 숨길수 있다.
protocol Car {
associatedtype Identifier
var id: Identifier {get}
}
struct HyunDai: Car {
let id: String
init(id: String) {
self.id = id
}
}
struct KIA: Car {
let id: String
init(id: String) {
self.id = id
}
}
기존 프로토콜 사용이다. associatedType은 추상화를 이해 사용되는 것으로 struct부분에서 결정이된다.
그런데 여기서 나는 리턴타입으로 각각의 sturct가 아닌 그냥 Car 자체를 받고 싶다. 하지만여기서 바로 에러가 뜬다. any를 붙이라네..? 그 이유가 현재는 둘다 identifier가 String이 되었지만 어떤놈은 Int일수 있다. 즉 Car프로토콜을 채택받은 뭔가가 반환하겠지..? 근데 그게 몬데??이기 때문이다. 그리고 protocol에서 associatedType에 대한 요구조건이 있으면 generic constraint로만 쓸 수 있다. 오직 프로토콜만 딱 적어두면 아 이게 뭔타입이구나를 스위프트가 추론 불가.
여기서 Opaque type(불분명 타입)이 등장! some키워드를 붙이면 에러가 사라진다. 왜? 구현부에서 아 이게 현대 타입이구나 라는 인스턴스를 반환하기 때문. 그래서 이 Car Protocol에서 요구하는 associatedtype 혹은 self가 뭔지 스위프트가 정확하게 알수 있기 때문. 컴파일러가 정확하게 알고 있다.
- 구현부의 타입만 바꾼다면 다른 타입을 사용가능.
- 호출자에 의해서가 아닌 함수 그자체가 반환타입 정한다. (이것이 제너릭과의 차이점!!!!!)
- 외부에서 함수의 반환값 유형을 정확하게 알수 없고 함수 내부에서는 어떤 타입을 다루는지 정확히 알고 있는 타입이라고 한다.
채택하는 타입이 반환된다는점은 동일하지만 컴파일러가 어떤타입을 반환하는지 정확하게 아는것이 = Opaque type
이제 우리는 some View를 이해할 수 있다. View프로토콜을 준수하는 것들이 들어올수 있고 컴파일러가 어떤타입을 반환하는지 알고 처리해주는 것이다.
struct ContentView: View {
var body: HStack<TupleView<Text,Image>> {
HStack {
Text("Hello, world!") Image(systemName: "plus") } }
}
|
요놈을 some View로 해주면 아 뷰프로토콜 준수하는얘가 들어오겠구나 하면서 컴파일러가 처리해준다.
Any
벌써 길어졌는데 Any라는 얘까지 하고 끝내야겠다. 왜냐면 같이나오는 개념이라..
some일때는 [some Car]하면 [Kia, Kia,Kia,]여야지 [Kia, Hyundai,Kia] 요런식으로 섞여올수 없다. 내부적으로 동일한 타입을 사용해야하기에 하지만 Any키워드를 사용하면 가능하다. 하지만 Any키워드가 특별한 것은 더 있다.
공식영상을 보면 Any는 값이 상자안에 들어갈정도로 작을수 있지만 저렇게 소나 말같이 거대한 얘들은 값은 다른데 할당되고 그값에대한 포인터만 저장하는 경우도 있다고 한다. 우리는 이를 Static type은 같으나 dynamic type은 다르다
그전에 type Erasure를 알아야한다.
-> 구체적인 특정 타입을 추상적인 타입으로 바꾸는것. 즉 타입을 지워 추상화시키겠다. 저 상자를 씌운다 의미한다.
some에서는 상자가 없어 어? 너 닭이네 소네 말이네 다 알지만 상자를 씌워놓으면 나는 어? 저기 뭐가 들어있는지 모른다.
any를 붙이면 이것은 existential type이 된다고 한다.
some은 구체화한 타입을 제한하지만 Any는 추상화한다.(type Erasure)
Apple은 컴파일타임에 정해지는 some을 일반적으로 사용하고 진짜 필요할때만 Any를 사용하는것을 권장한다. 그 이유가 런타임때 정해지기 때문에 예측가능성이 떨어진다.
와 진짜 길다... 하지만 너무나 필요한 개념이다. 이해가 안가거나 어려운 부분이 있으면 댓글남겨주세요 언제든 수정하겠습니다.
참고 : https://www.hackingwithswift.com/articles/187/how-to-use-opaque-return-types-in-swift-5-1
'SWIFTUI' 카테고리의 다른 글
TCA(1)- (mvvm...-> NEXT?) (0) | 2024.07.04 |
---|---|
go back to basic - @main 플젝만들면 항상생기는 파일 이건 몰까? (0) | 2024.03.01 |
근본으로 돌아가자(4)-@State,@StateObject,@ObservedObject (2) | 2024.02.27 |
@ViewBuilder & @resultBuilder (1) | 2024.02.26 |
근본으로 돌아가자(3)-View Layout (2) | 2024.02.26 |