2016-11-20 12 views

답변

3

구문 Element: XX이 프로토콜 또는 Element 파생 된 클래스를해야 X에 의해 정의되는 Element에 형 제약 조건을 inpose하는 것을 의미합니다. 이 문제를 해결하려면 (값 유형) 요소 UInt8을 사용하는 배열에서만 사용할 수있는 Array의 확장을 구성하려면 UInt8 만 준수하는 프로토콜을 정의하고이 프로토콜을 확장 프로그램의 유형 제약 조건으로 사용할 수 있습니다 . 예 : 현재 구현에서

protocol MyType {} 
extension UInt8: MyType {} 

extension Array where Element: MyType { 
    // ... 
} 

는 확장 내의 코드는 MyType 프로토콜에 청사진을하지 않습니다 (즉, 현재, 아무것도) 무엇보다 Element 유형에 대한 자세한 아무것도 모른다. 확장 프로그램을 통해 달성하려는 목표에 따라 UInt8에 구현할 수있는 청사진을 이미 MyType에 추가 할 수 있습니다 (예 : UInt8). 일부 이니셜 라이저. 그러나보다 합리적인 접근법은 UInt8이 유용한 프로토콜 UnsignedInteger, EquatableComparable을 따르는 사실을 이용하는 것입니다.

protocol MyType {} 
extension UInt8: MyType {} 

extension Array where Element: MyType & UnsignedInteger { 
    mutating func superfluouslyReplaceAllElements(with value: Element) { 
     self = self.map { $0.advanced(by: $0.distance(to: value)) } 
    } /* using 'advanced(by:)' and 'distance(to:)' methods of 
     'Element', blueprinted in 'UnsignedInteger', to which 
     'Element' conforms */ 

    mutating func elementsSquaredWithOverflow() -> Bool { 
     var overflow = false 
     self = self.map { 
      let result = Element.multiplyWithOverflow($0, $0) 
      overflow = overflow || result.overflow 
      return result.0 
     } 
     return overflow // did at least one element cause an arithmetic overflow? 
    } 
} 

var foo: [UInt8] = [14, 87, 13, 240] 
print(foo.elementsSquaredWithOverflow()) // true (at least one arithmetic overflow) 
print(foo) // [196, 145, 169, 0] 

foo.superfluouslyReplaceAllElements(with: 42) 
print(foo) // 42, 42, 42, 42 

var bar: [UInt16] = [14, 87, 13, 240] 
bar.superfluouslyReplaceAllElements(with: 42) 
    /* error: type 'UInt16' does not conform to protocol 'MyType' 
     OK, as expected!           */ 

이 :하지만 (즉, 만 UInt8) 자신의 프로토콜 MyType에 부합 입력 이러한 요소를 제한, 확장에서의 : 프로토콜 구성을 사용하여 이러한 프로토콜에 의해 청사진을 모든 방법 Element 쉽게 이용할 수 있습니다 그러나 프로토콜과 타입 제약에서의 짧은 교훈 일 뿐이다. 바이트 컨텍스트에서 UInt8 시퀀스로 작업하려는 경우 사용자의 질문에 대한 @vadian : s의 조언을 따르십시오.

+0

UInt64 용 휠을 다시 발명해야하는 이유는 무엇입니까? 게으른 애플 mofos. 배열 및/또는 범위를 재발 명할 필요없이 UINT64 또는 32 벡터를 사용할 수 없습니다. 프로토콜에 SignedInteger를 넣어야한다고 생각합니다. –

+0

@μολὼν.λαβέ Swift 3.1이 출시되면 (현재 Xcode 8.3 이상 베타 버전에서 사용 가능) 콘크리트 유형 요구 사항에 대한 일반 유형을 확장 할 수 있습니다. 'extension Array where Element == UInt8 {...}'위의 경우 "더미"프로토콜 인 MyType이 필요 없습니다. 'UInt64' 또는'UInt32'를 다시 발명하는 것에 대한 토론을 따르지는 않지만,이 새로운 기능으로 인해이를 단순화 할 수 있습니다. Swift 및 Swift 표준 라이브러리를 개선하는 방법에 대한 구체적인 제안이 있으면 [Swift Evolution 메일 목록] (https://apple.github.io/swift-evolution/)에서 논의 해 볼 수 있습니다. – dfri

+0

좋아, UInt가 제 3의 클래스 시민처럼 대우받는 방법에 관한 나의 호언 장담을 게시 할 것이다. –