这是我的代码:
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'
Ofcourse,修复将被加入铸:
as! GenericClass<UITableViewCell>.SomeEnum
,其结果在该丑陋的代码:
func callOtherClass() {
OtherClass.handle(property: enumProperty) as! GenericClass<UITableViewCell>.SomeEnum
}
但是为什么我需要投射? self
被定义为GenericClass,其中T
始终是UITableViewCell
。该方法handle
期望的签名。
在某些情况下是否需要这种施法,因为在某些情况下这样做会/可能失败?我不希望Swift会随机要求我插入强制施法。我希望斯威夫特可以只推断出类型,并认为它是安全的,但不知何故,斯威夫特不同意我的观点。
答案 0 :(得分:2)
使您的静态方法也通用,并为从UITableViewCell
继承的参数创建通用约束。然后在方法参数中使用该通用参数
class OtherClass {
static func handle<T: UITableViewCell>(property: GenericClass<T>.SomeEnum) {}
}
答案 1 :(得分:2)
这里的问题是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) {}
}