簡體   English   中英

為什么“即使有不同的條件界限,也不能有多個一致性”?

[英]Why 'there cannot be more than one conformance, even with different conditional bounds'?

我希望 Swift 使我能夠為在where塊中具有指定條件的類型創建擴展。 我想象我可以使用依賴於具體泛型類型值 ( T ) 的不同擴展來擴展相同的泛型類型。 但不是。 以下示例演示了我的問題:

protocol P {    
    associatedtype Prop 
    var property: Prop { get }
}

enum E<T: P> {
   case single(T)
   case double(T)
}

extension E: P where T.Prop == Int {
   var property: Int {
      switch self {
      case .single(let o): return o.property
      case .double(let o): return o.property * 2
      }
   }
}

extension E: P where T.Prop == String {
   var property: String {
      switch self {
      case .single(let o): return o.property
      case .double(let o): return o.property + o.property
      }
   }
}

struct Int4: P {
   var property: Int {
       return 4
   }
}

struct StringHello: P {
    var property: String {
        return "Hello" 
    }
}

print(E.single(Int4()).property)
print(E.double(StringHello()).property)

以下錯誤和注釋是編譯的結果。

錯誤:“E”與協議“P”的一致性沖突; 即使有不同的條件邊界extension E: P where T.Prop == String {也不能有多個一致性

注意:'E' 聲明符合協議 'P' 此處extension E: P where T.Prop == Int {

真的不可能嗎? 為什么? 我可以用我的代碼做什么才能成功?


一些細節來證明我的真實情況下的問題。
我有一些通用枚舉,它與許多不同的包裝類型一起使用。

enum Color<T> {
  case red(T), green(T)

  func map<T2>(_ transform: (T) -> T2) -> Color<T2> {
    switch self {
    case .red(let o): return .red(transform(o))
    case .green(let o): return .green(transform(o))
    }
  }
}

很多時候,我需要 Color 的不同擴展以使其符合不同的協議,具體取決於包裝類型。 有時這些協議具有相同的基本(超級)協議,因此,我遇到了當前的問題。 有時我無法擴展 Color 以符合所有派生協議的基本(超級)協議,因為我需要不同的實現。

如前所述,您不能只進行這種擴展。 但是,您可以像這樣使用 hack:

protocol SomeExtension {
    func doSomething()
}

extension SomeExtension {
    func doSomething() {
        print("Do nothing or error")
    }
}

extension SomeExtension where Self == [String] {
    func doSomething() {
        print("String")
    }
}

extension SomeExtension where Self == [Int] {
    func doSomething() {
        print("Int")
    }
}

extension Array: SomeExtension { }

let stringsArr = ["a", "b", "d"]
let numbersArr = [1, 2, 3]
stringsArr.doSomething()
numbersArr.doSomething()

在控制台你可以看到

String
Int

不可能嗎? 是和否。 它目前在 Swift 中是不可能的,因為它已經實現了。 原則上是可以實現的。

它的名稱是“重疊一致性”,它被明確和有意地拒絕。 您可以在SE-0143 條件一致性的“考慮的替代方案”部分中找到基本原理。 TL;DR 是:因為它真的很復雜。

在不知道更多關於你到底想用它做什么的情況下,我們可以提供的方向不多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM