这是我的代码:
class GenericClass<T: UITableViewCell> {
let enumProperty = SomeEnum.myValue
enum SomeEnum {
case myValue
}
func callOtherClass() {
OtherClass.handle(property: enumProperty) // Compile error
}
}
class OtherClass {
static func handle(property: GenericClass<UITableViewCell>.SomeEnum) {}
}
为什么会出现编译错误:
Cannot convert value of type 'GenericClass.SomeEnum' to expected argument type 'GenericClass.SomeEnum'
当然,修复方法是添加 Actor 阵容:
as! GenericClass<UITableViewCell>.SomeEnum
这会导致这个丑陋的代码:
func callOtherClass() {
OtherClass.handle(property: enumProperty) as! GenericClass<UITableViewCell>.SomeEnum
}
但是为什么我需要转换? self
被定义为 GenericClass,其中 T
始终是 UITableViewCell
。方法handle
需要该签名。
是否有任何情况需要此强制转换,因为在某些情况下这会/可能失败?我不希望 Swift 只是随机要求我插入强制强制转换。我希望 Swift 能够推断类型并认为它是安全的,但不知何故,Swift 不同意我的观点。
最佳答案
这里的问题是 SomeEnum
实际上是GenericClass<T>.SomeEnum
。没有任何 promise T
正是UITableViewCell
,所以它与 GenericClass<UITableViewCell>
不兼容(generics are not covariant)。
通常在这种情况下,您想要做的是移动 SomeEnum
GenericClass
之外,因为它实际上没有什么是通用的:
enum SomeEnum {
case myValue
}
class GenericClass<T: UITableViewCell> {
let enumProperty = SomeEnum.myValue
func callOtherClass() {
OtherClass.handle(property: enumProperty) // Compile error
}
}
class OtherClass {
static func handle(property: SomeEnum) {}
}
但是,如果有理由使其通用,请参阅 Robert Dresler 的答案,这就是正确地专门化该函数的方法:
class OtherClass {
static func handle<T: UITableViewCell>(property: GenericClass<T>.SomeEnum) {}
}
关于swift - 为什么我需要将属性强制转换为与该属性具有相同签名的泛型方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54468558/