Swift 涉及泛型时找不到重载
Swift cannot find overload when generics involved
我有以下代码:
protocol MyEnum {
}
class MyClass {
func append(_ value: UInt8) {
print("uint8 \(value)")
}
func append(_ value: UInt16) {
print("uint16 \(value)")
}
func append<T: MyEnum>(_ value: T) {
print("myenum \(value)")
}
}
let c = MyClass()
func appendAny<T>(_ value: T) {
switch value {
case let u8 as UInt8:
c.append(u8)
case let u16 as UInt16:
c.append(u16)
case let myenum as MyEnum:
c.append(myenum)
default:
assert(false)
}
}
编译器针对第 c.append(myenum)
行报告错误,指出
Cannot invoke 'append' with an argument list of type (MyEnum)
请向我解释为什么会发生这种情况以及在这种情况下正确的解决方案是什么。我想保留我的重载,因为当使用具体的 MyEnum
实例调用时,一切正常。
正如 Martin 在他的评论中指出的那样,您应该将最终的 append()
重载更改为:
func append(_ value: MyEnum) {
print("myenum \(value)")
}
因为您想将该值视为 "an instance of a protocol",而不是 "instance of a concrete type that happens to conform to the protocol"。具有协议类型的实例不是也符合该协议的具体类型。
另一个注意事项:既然您并没有真正使用通用约束或类型 T
的任何编译时属性(仅运行时转换),为什么不将 appendAny
更改为:
func appendAny(_ value: Any) {
switch value {
case let u8 as UInt8:
c.append(u8)
case let u16 as UInt16:
c.append(u16)
case let myenum as MyEnum:
c.append(myenum)
default:
assert(false)
}
}
我有以下代码:
protocol MyEnum {
}
class MyClass {
func append(_ value: UInt8) {
print("uint8 \(value)")
}
func append(_ value: UInt16) {
print("uint16 \(value)")
}
func append<T: MyEnum>(_ value: T) {
print("myenum \(value)")
}
}
let c = MyClass()
func appendAny<T>(_ value: T) {
switch value {
case let u8 as UInt8:
c.append(u8)
case let u16 as UInt16:
c.append(u16)
case let myenum as MyEnum:
c.append(myenum)
default:
assert(false)
}
}
编译器针对第 c.append(myenum)
行报告错误,指出
Cannot invoke 'append' with an argument list of type (MyEnum)
请向我解释为什么会发生这种情况以及在这种情况下正确的解决方案是什么。我想保留我的重载,因为当使用具体的 MyEnum
实例调用时,一切正常。
正如 Martin 在他的评论中指出的那样,您应该将最终的 append()
重载更改为:
func append(_ value: MyEnum) {
print("myenum \(value)")
}
因为您想将该值视为 "an instance of a protocol",而不是 "instance of a concrete type that happens to conform to the protocol"。具有协议类型的实例不是也符合该协议的具体类型。
另一个注意事项:既然您并没有真正使用通用约束或类型 T
的任何编译时属性(仅运行时转换),为什么不将 appendAny
更改为:
func appendAny(_ value: Any) {
switch value {
case let u8 as UInt8:
c.append(u8)
case let u16 as UInt16:
c.append(u16)
case let myenum as MyEnum:
c.append(myenum)
default:
assert(false)
}
}