簡體   English   中英

Swift枚舉涉及依賴協議的多種泛型類型

[英]Swift enum multiple generic types involving depending protocols

protocol ProtocolA {
    func someFunc() -> Any
}

protocol ProtocolB: ProtocolA {
    var someVar: Any { get }
}

enum MyEnum<T: ProtocolA, U: ProtocolB> {
    case A(T)
    case B(U)
}

protocol DataObject {
    ...
}

extension DataObject where Self: ProtocolB {
    func doSomething() {
        let x = MyEnum.B(self)
        /// Compiler error:
        /// Cannot invoke 'B' with an argument list of type '(Self)'
    }
}

我不明白為什么上面給我一個錯誤。 奇怪的是,刪除兩個枚舉通用約束中的任何一個,使枚舉只有一個約束,解決了問題......

請注意,ProtocolB擴展了ProtocolA。 與通用約束一起使用時,是否不支持此功能?


UPDATE

MyEnum更改MyEnum可以解決問題:

enum MyEnum {
    typealias T = ProtocolA
    typealias U = ProtocolB

    case A(T)
    case B(U)
}

但是,我仍然不明白為什么......

這個錯誤有點誤導。 讓我們簡化問題來探索它。

protocol ProtocolA {}

protocol ProtocolB: ProtocolA {}

enum MyEnum<T: ProtocolA, U: ProtocolB> {
    case A(T)
    case B(U)
}

struct AThing: ProtocolA {}

struct BThing: ProtocolB {}

let bThing = BThing()
let thing = MyEnum.B(bThing) // error: cannot invoke 'B' with an argument list of type '(BThing)'

所以現在我們DataObject了同樣的問題而不需要DataObject 為什么這會失敗?

MyEnum是通用的。 這意味着為了創建具體類型,它必須知道TU的類型。 您提供了對這些類型的約束(一個符合ProtocolA ,另一個符合ProtocolB ),但您沒有具體說明它們是什么類型。

當我們到達這一行時:

let thing = MyEnum.B(bThing)

什么類型的thing 通過類型推斷,我們可以弄清楚U是什么,但是什么是T

let thing: MyEnum<?, BThing> = MyEnum.B(bThing)

這里沒有足夠的上下文來解決它,所以我們必須明確地告訴編譯器:

let thing = MyEnum<AThing, BThing>.B(bThing)

所以完整類型的thingMyEnum<AThing, BThing> ,這是一種與MyEnum<OtherAThing, BThing>不同的類型。 (正如[Int][String]類型不同,這就是為什么let xs = []在沒有顯式類型定義的情況下不會編譯。)

你的第二個例子不通用,所以沒有問題。 它簡化為:

enum MyEnum {
    case A(ProtocolA)
    case B(ProtocolB)
}

綁定類型只是重命名類型,它們不會創建新類型(如未綁定的類型,或者Swift 2.2調用它, associatedtype )。 所以我們知道A接受任何ProtocolAB接受任何ProtocolB ,並且所有MyEnum實例具有相同的類型。

錯誤是不幸的,因為編譯器很困惑。 如果將此簡化為最基本的情況,則會得到更明確的錯誤。 這失敗的原因與您的示例完全相同。

enum MyEnum<T> {
    case A
}

let x = MyEnum.A // error: generic parameter 'T' could not be inferred

暫無
暫無

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

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