2017년 1월 4일 수요일

Swift 4에 추가될 사항 살펴보기

## 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


댓글 없음:

댓글 쓰기

Building asynchronous views in SwiftUI 정리

Handling loading states within SwiftUI views self loading views View model 사용하기 Combine을 사용한 AnyPublisher Making SwiftUI views refreshable r...