簡體   English   中英

Swift枚舉中通用關聯值的確切限制是什么?

[英]What's the exact limitation on generic associated values in Swift enums?

我試圖理解Swift中具有通用關聯值的枚舉的確切限制。

您可能認為它們受支持,因為Optional是這樣的類型。 以下是在Swift標准庫中定義Optional的代碼:

enum Optional<T> : Reflectable, NilLiteralConvertible {
    case None
    case Some(T)
// ...
}

看起來像case成員Some有一個變量類型T的關聯值,對嗎?

但是, 在Swift中的函數編程 (第87頁)一書中提到,不支持這樣的類型:

我們想在與Success相關的結果中定義一個通用的新枚舉:

  枚舉結果<T> {\n     案例成功(T)\n     案例失敗(NSError) \n } 

遺憾的是,當前的Swift編譯器不支持通用關聯值。

事實上,如果您將該片段輸入編譯器,則會出現錯誤( error: unimplemented IR generation feature non-fixed multi-payload enum layout )。

那么這里發生了什么? 它只是一般不支持,但作為特殊情況支持Optional嗎? 有沒有辦法看看Optional如何獲得這種特殊支持? 或者,如果其他標准庫類型也獲得特殊支持?

在Swift 2中(作為Xcode 7的一部分),對關聯值沒有限制。 所以,隨意跳舞,像這樣的節拍:

enum YouCanGoWith<T, U> {
    case This(T)
    case That(U)
    case Us
}

現在,如果您正在尋找成功或錯誤類型的枚舉,您可能想停下來思考為什么......因為Swift 2還帶來了一個新的錯誤處理模型。 所以你不需要像函數的返回值這樣的類型 - 你可以像這樣聲明它:

func walkWith(rhythm: Bool) throws -> Place { /* ... */ }

...如果你成功之后,主叫方總是得到一個(非可選) Place用於向沃肯。 並且 - 與使用結果分開 - 調用者決定如何處理,吞下或傳播錯誤。

有關詳細信息,請參閱Swift編程語言 錯誤處理 仔細觀察 - 語法看起來有點像你在其他一些語言中看到的異常模型,但Swift錯誤是一種完全不同的動物。

(當然, throws模型特定於同步調用。如果你要聲明異步進程的回調,回調閉包接收成功異步工作或錯誤的結果 - 成功或錯誤類型仍然完全適當。)

這個答案在Swift 2中已經過時了。請參閱rickster對Swift 2更新的回答。

你的意見是對的。 如果其中任何一個具有未知大小,則不能有多個具有關聯數據的案例。 值類型可以是任何大小(因為它們被復制)。 引用類型(如對象)具有已知大小,因為它們存儲指針。

對此的典型解決方案是創建一個額外的包裝類來保存泛型類型,就像FP書一樣。 按慣例,每個人都稱之為Box 有理由希望Swift團隊將在未來解決這個問題。 如您所知,他們將其稱為“未實現”而非“不受支持”。

Box的典型實現:

final public class Box<T> {
  public let unbox: T
  public init(_ value: T) { self.unbox = value }
}

暫無
暫無

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

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