这是我的代码:

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/

10-12 01:08