2016-11-20 52 views
0

我想延長UINT8值的數組,所以我在斯威夫特3寫了這個代碼:斯威夫特延長UINT8陣列

extension Array where Element: UInt8 { 

} 

但我得到這個錯誤:

類型「Self.Generator .Element'受限於非協議類型'UInt8'

那麼我該如何解決它?

+2

看看Swift 3中的'Data'。它基於'UInt8'並且符合'Sequence' – vadian

回答

3

語法Element: X意味着要inpose類型約束上ElementX,其中X必須是一個協議或從中Element被派生的類定義。作爲一種解決方法,如果您想構造Array的擴展,該擴展只適用於(值類型)元素爲UInt8的數組,則可以定義一個只有UInt8符合的協議,並將該協議用作擴展中的類型約束。例如。

protocol MyType {} 
extension UInt8: MyType {} 

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

在其當前實現,擴展中的任何代碼什麼都不知道更多關於比什麼是在MyType協議blueprinted(即,目前沒有)的Element類型。根據您的擴​​展需要達到的目標,您可以將藍圖添加到MyType,您知道這些藍圖已通過UInt8可用的實施方式實現,例如,一些初始化程序。但更明智的做法是利用這樣一個事實,即UInt8符合有用的協議UnsignedInteger,EquatableComparable。通過使用協議的組合物,通過這些協議blueprinted所有方法可以容易地提供給Element:■在延伸,但是限制這些元件輸入符合自己的協議MyType(即,僅UInt8):

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序列,請在您的問題的評論中關注@vadian:的建議。

+0

爲什麼我不得不重新發明UInt64的車輪?懶惰的蘋果mofos。不能使用UINT64或32的向量而不必重新創建數組和/或範圍。我認爲你應該把SignedInteger放在協議中。 –

+0

@μολὼν.λαβέ一旦Swift 3.1發佈(目前在Xcode 8.3+ beta中可用),您將能夠擴展具體類型要求的泛型類型,例如, '擴展數組,其中Element == UInt8 {...}'在這種情況下,我們不需要上面的「虛擬」協議'MyType'。我沒有按照你對重新設計'UInt64'或'UInt32'的討論,但是這個新功能可能會爲你簡化這個。如果你對如何改進Swift和Swift std庫有一些具體的建議,你可以嘗試在[Swift Evolution郵件列表](https://apple.github.io/swift-evolution/)上討論它。 – dfri

+0

好吧,我會發表我的咆哮關於UInt如何被對待像一個三等公民。 –