这是我的代码:
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) {}
}
为什么会出现编译错误:
无法将“GenericClass.SomeEnum”类型的值转换为预期值
参数类型“GenericClass.SomeEnum”
当然,修复方法是添加演员表:
as! GenericClass<UITableViewCell>.SomeEnum
这导致了这个丑陋的代码:
func callOtherClass() {
OtherClass.handle(property: enumProperty) as! GenericClass<UITableViewCell>.SomeEnum
}
但为什么我需要演员?
self
定义为GenericClass,其中T
始终是一个UITableViewCell
。方法handle
需要该签名。在某些情况下,这会/可能会失败,是否需要这种演员阵容?我不希望斯威夫特只是随机要求我插入一个强制施法。我希望斯威夫特能推断出这些类型,并认为它是安全的,但不知何故,斯威夫特不同意我的观点。
最佳答案
这里的问题是SomeEnum
实际上是GenericClass<T>.SomeEnum
。没有保证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/