这是我的代码:
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
需要该签名。
在某些情况下是否需要这种强制转换,因为在某些情况下,这种转换将会/可能会失败?我不希望斯威夫特只是随机要求我插入强制施放。我希望Swift可以推断出类型并认为它是安全的,但是无论如何,Swift与我不同意。
这里的问题SomeEnum
是实际上GenericClass<T>.SomeEnum
。没有任何保证T
是完全正确的UITableViewCell
,因此它与GenericClass<UITableViewCell>
(泛型不是协变的)不兼容。
通常,在这种情况下,您想要做的是移至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) {}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句