https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md
associated type에 where를 쓸 수 있도록 한다.
protocol Sequence { associatedtype Iterator : IteratorProtocol associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == Iterator.Element ... }
위의 문법을 허락함으로서 아래와 같이 상위 protocol의 associated type에 제한을 걸 수 있게 된다.
protocol IntSequence : Sequence where Iterator.Element == Int { ... }
하지만, 아래처럼 상위 protocol에 없는 것에 제한을 걸 수는 없고,
protocol SomeSequence : Sequence where Counter : SomeProtocol { // error: Use of undefined associated type 'Counter' associatedtype Counter }
아래처럼 사용되어야 한다.
protocol IntSequence : Sequence { associatedtype Counter : SomeProtocol }
## 0143 - Conditional conformances
type argument가 어떤 조건을 만족하는 경우 generic type도 특정 조건에 만족하도록 한다. 예를 들어, Array의 element가 Equatable을 만족하는 경우 Array도 Equatable이 되도록 한다.
extension Array: Equatable where Element: Equatable { static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool { ... } }
multiple conformance는 허락하지 않는다.
struct SomeWrapper<Wrapped> { let wrapped: Wrapped } protocol HasIdentity { static func ===(lhs: Self, rhs: Self) -> Bool } extension SomeWrapper: Equatable where Wrapped: Equatable { static func ==(lhs: SomeWrapper<Wrapped>, rhs: SomeWrapper<Wrapper>) -> Bool { return lhs.wrapped == rhs.wrapped } } // error: SomeWrapper already stated conformance to Equatable extension SomeWrapper: Equatable where Wrapped: HasIdentity { static func ==(lhs: SomeWrapper<Wrapped>, rhs: SomeWrapper<Wrapper>) -> Bool { return lhs.wrapped === rhs.wrapped } }
또한 상속관계에 의해서 조건의 만족이 모호해지면 안된다.
protocol P { } protocol Q : P { } protocol R : P { } struct X<T> { } extension X: Q where T: Q { } extension X: R where T: R { } // error: X does not conform to protocol P; add // // extension X: P where <#constraints#> { ... } // // to state conformance to P.
하지만, 아래와 같은 경우(S < R < P)는 컴파일러가 더 일반적인(more general) 경우(R)에 대해서 내부적으로 생성하여 동작하도록 한다.
protocol R: P { } protocol S: R { } struct Y<T> { } extension Y: R where T: R { } extension Y: S where T: S { }
/// compiler produces the following implied inherited conformance: extension Y: P where T: R { }
## 0110 - Distinguish between single-tuple and multiple-argument function types
현재는 아래처럼 one tuple argument인 경우와 multiple arguments인 경우에 대한 구별이 명백하지 않다.
let fn1 : (Int, Int) -> Void = { x in // The type of x is the tuple (Int, Int). // ... } let fn2 : (Int, Int) -> Void = { x, y in // The type of x is Int, the type of y is Int. // ... }
n parameter(n > 1)인 경우에 fn2만이 맞는 표현이 되도록 한다. one tuple parameter가 n개의 요소를 가지는 경우는 아래와 같이 괄호로 감싸서 써주도록 한다.
let a : ((Int, Int, Int)) -> Int = { x in return x.0 + x.1 + x.2 }
## 0146 - Package Manager Product Definitions
## 0148 - Generic Subscripts
subscripts도 generic이 될 수 있도록 한다.
extension Dictionary { subscript<Indices: Sequence>(indices: Indices) -> [Iterator.Element] where Indices.Iterator.Element == Index { // ... } }
하나 더! subscripts에 default arguments도 있도록 한다.
subscript<A>(index: A? = nil) -> Element { // ... }
## 0149 - Package Manager Support for Top of Tree development
## 0150 - Package Manager Support for branches
## 0154 - Provide Custom Collections for Dictionary Keys and Values
댓글 없음:
댓글 쓰기