Swift 通用函数类型排序

Swift Generic Function Types Ordering

假设我有:

protocol A {
    ...
}
protocol B: A {
    ... // some associated types
}
struct C: B {
    ...
}

我想创建一个函数 foo(of:) 来分隔不同类型的操作。喜欢:

func foo<AHolder: A>(of: AHolder) { ... }

func foo<BHolder: B>(of: BHolder) { ... }

func foo(of: C) { ... }

然而,所有 foo(of:) 的调用都会进入 foo<AHolder: A>(of: AHolder) 的情况,而不是它们相应的类型,即使 type(of:) 函数 returns a C 为参数。

我曾尝试使用 in 语句来分隔类型,但是当相关类型仍然未知时 in 不会针对协议进行编译(即上面显示的 B 情况) .

有什么想法或建议吗?

您需要在调用站点提供类型信息,考虑这两个结构:

struct AHolder: A {
    
}
struct BHolder: B {
    
}

假设您的 foo 方法只打印:

func foo<AHolder: A>(of: AHolder) {
    print("AHolder")
}

func foo<BHolder: B>(of: BHolder) {
    print("BHolder")
}

func foo(of: C) {
    print("C")
}

这很好用:

foo(of: C()) // prints "C"
foo(of: AHolder()) // prints "AHolder"
foo(of: BHolder()) // prints "BHolder"

为什么?因为 在调用站点 编译器知道您要打印 C 的实例、AHolder 的实例和 BHolder 的实例。

现在试试这个:

let a: some A = BHolder()
foo(of: a) // prints "AHolder"
let b: some B = C()
foo(of: b) // prints "BHolder"

在调用点,编译器只知道a是一个some类型的对象,符合A,并且 b 是 some 类型的对象,符合 B,所以即使变量确实是 BHolderC 的实例,编译器不知道这一点,并使用与其 知道的类型相匹配的重载 即。 foo<AHolder: A>(of:)foo<BHolder: B>(of:).