티스토리 뷰
안녕하세요 :) Zedd입니다.
Swift 5.7 이어서~~~
다음과 같은 간단한 Generic 메소드를 봅시다.
func compute<C: Collection>(_ values: C) -> Int {
return values.count
}
Collection protocol을 conform하고있는 generic parameter를 받도록 되어있습니다.
func compute<C: Collection>(_ values: C) -> Int {
return values.count
}
compute([1, 2, 3]) // 3
compute(["Zedd": "안녕"]) // 1
그래서 Array나 Dictionary같은 Collection 들을 넣을 수 있게 됩니다.
# default value expression with a generic parameter
일반 메소드 parameter에 default value를 넣을 수 있듯이,
generic parameter에도 default value를 넣어보고싶지만..
func compute<C: Collection>(_ values: C = ✅[1, 2, 3]✅) -> Int {
return values.count
}
// 🚫 Default argument value of type '[Int]' cannot be converted to type 'C'
컴파일 에러가 나는데요. 현재 semantic rule상 안된다고 함;;
그래서 SE-0347 에서는
call site에서 명시적으로 파라미터를 안줬을 때 default value로 넣어둔 concrete type에 대해 타입 추론을 허용하자!
를 제안합니다.
Swift 5.7에서는
func compute<C: Collection>(_ values: C = [1, 2, 3]) -> Int {
return values.count
}
compute([1, 2, 3]) // 3
compute(["Zedd": "안녕"]) // 1
compute() // 3 ✅
위와같이 call site에서 명시적으로 파라미터를 안줬을 때 default value로 넣어둔 [1, 2, 3]으로 타입 추론을 한다는 것이죠.
하지만 아묻따 generic parameter에 default value를 넣을 수 있는 것은 아니고,
여전히 컴파일에러가 나는 상황이 있는데요.
func compute<T, U: Collection>(value: T = 42,
collection: U) where U.Element == T {
}
// 🚫 Cannot use default expression for inference of 'T' because requirement 'T == U.Element' refers to other generic parameters
위와 같은 상황에서 여전히
자 위에 T에 42라는 default value를 줬죠?
이러한 default parameter와 관련하여 암시적 or 명시적으로 call site에서 타입을 유추할 수 있다면
concrete type으로 입력된 default value는 여전히 컴파일 에러가 납니다.
여기서는 U.Element = T라는 요구조건이 있고 여기서 T의 타입을 유추할 수 있기 때문에 컴파일 에러가 나는 것이죠.
func compute<T, U: Collection>(value: T = 42,
collection: U = []) where U.Element == Int {
} ✅
만약 이렇게 T와 U가 서로 독립적으로 있다면 T의 default value가 허용됩니다.
또 하나 허용 안되는 경우를 볼까요
Swift 공식문서 - Generic 파트에 있는 메소드입니다.
func findIndex<T: Equatable>(of valueToFind: T, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
여기서 파라미터에 default value를 넣으면 잘 될 것 같지만,
func findIndex<T: Equatable>(of valueToFind: T = 42 ✅, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
// 🚫 cannot use default expression for inference of 'T' because it is inferrable from parameters #0, #1
컴파일 에러가 나게 됩니다.
첫번째, 두번째 파라미터로 (암시적 or 명시적으로) T를 유추할 수 있기 때문에.. default value를 넣어줄 수 없습니다.
ㅎ
ㅡ
ㅁ.....
Swift Generic이 runtime에 타입이 결정되는데,
func compute<C: Collection>(_ values: C = [1, 2, 3]) -> Int {
return values.count
}
compute([1, 2, 3]) // 3
compute(["Zedd": "안녕"]) // 1
compute() // 3 ✅
위와 같을 때는 아직 타입을 유추할 수 없고...
func findIndex<T: Equatable>(of valueToFind: T = 42 ✅, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
// 🚫 cannot use default expression for inference of 'T' because it is inferrable from parameters #0, #1
이때는 call site에서 T를 유추할 수 있기 때문에.. (첫번째, 두번째 파라미터에 같은 타입을 넣어줘야하니까..) 안되는 것 같네요.
틀린 부분이 있으면 댓글 남겨주세요!
요거 왜 안되는지, 되는지 잘 이해가 안가서 ㅎㅎ;; 계속 봤네요.
[참고]
- SE-0347
'Swift' 카테고리의 다른 글
[Swift 5.7] Actor 관련 warning들 원인 파악해보기 (0) | 2023.01.31 |
---|---|
[Swift] Opaque Type (4) | 2022.12.23 |
[Swift 5.7] Multi-statement closure type inference (1) | 2022.07.09 |
[Swift 5.7] if let shorthand (1) | 2022.07.09 |
Swift 5.6 ) Introduces existential any (9) | 2022.04.03 |
- swift array
- 제이슨 파싱
- 피아노
- fastlane
- swift delegate
- Swift
- UIBezierPath
- Combine
- actor
- swift tutorial
- WKWebView
- Accessibility
- WidgetKit
- swift 공부
- swift3
- 스위프트
- WWDC
- IOS
- ios 13
- np-complete
- Git
- 회고
- iOS delegate
- 스위프트 문법
- Xcode
- np-hard
- github
- SwiftUI
- swift sort
- FLUTTER
- Total
- Today
- Yesterday