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
,所以即使变量确实是 BHolder
和 C
的实例,编译器不知道这一点,并使用与其 知道的类型相匹配的重载 即。 foo<AHolder: A>(of:)
和 foo<BHolder: B>(of:)
.
假设我有:
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
,所以即使变量确实是 BHolder
和 C
的实例,编译器不知道这一点,并使用与其 知道的类型相匹配的重载 即。 foo<AHolder: A>(of:)
和 foo<BHolder: B>(of:)
.