## 0142 Permit where clauses to constrain associated types
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