【问题标题】:Swift generic type castSwift 泛型类型转换
【发布时间】:2014-12-22 03:20:07
【问题描述】:

我有一个泛型类,其中有一组泛型类型。不,我想根据数组中的类做一些操作。我有 2 个类:Person 和 House(无继承)。但是这段代码不起作用:

let allValues = [T]()
if allValues[0] is Person { 
     let values = (allValues as [Person])
}

但这不起作用,因为 T 与“Person”不同。我需要做什么?感谢您的帮助。

【问题讨论】:

    标签: generics swift ios8


    【解决方案1】:

    你不能这样做(或者至少,不能不跳过一些相当曲折和不明智的箍)。您认为T 更像Any 类型,这是一种可以容纳任何其他类型的类型,并且您可以在运行时使用as(或者最好是as?)转回真实类型。

    但是泛型不是这样工作的。在您的代码中,泛型T 将在编译时替换为实际类型,并且该类型可能不是Person。如果是这样,上面的代码会做什么?

    您真正想要实现的底层功能是什么?人和房子有很大的不同,所以你真的需要编写一个对它们都通用的函数吗?

    【讨论】:

    • 我想根据一些值绘制一些图表,但我只是想我可以实现一个协议,不是吗?
    • 是的,听起来更像您要找的东西。
    【解决方案2】:

    我同意 Oliver BorchertAirspeed Velocity:这类问题应该使用协议来解决。

    但是,您可以使用此语法执行您询问的强制转换:

    let values = allValues as Any as [Person]
    

    现在我看到了 2 个问题:

    1. 您的 IF 将崩溃,因为您的数组 allValues 包含 0 元素,您正在访问第一个元素(不存在)。
    2. allValues 可以在第一个元素处有一个 Person 和一些东西 否则在第二个位置。这使得在仅评估第一个元素后进行强制转换很危险。

      例子

      类 LifeForm {}

      类人:LifeForm {}

      T 等于 LifeForm。

    我认为以下版本更安全,因为您直接评估类型 T。

    class Things<T>{
        func doSomething() {
            let allValues = [T]()
            // populate allValues....
            if T.self is Person.Type {
                println("List of Person")
                let values = allValues as Any as [Person]
            }
        }
    }
    

    重要提示:我提供此代码只是为了显示语法。我不喜欢这个 abborach(同样,协议会更好),因为类 Things 包含特定于 Person 的逻辑。 理想情况下,Things 应该对 Person 一无所知,因为 Things 是一个泛型类。

    【讨论】:

    • 嗯,你说得对,这看起来很糟糕 - 我会使用协议,但无论如何谢谢你:]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    相关资源
    最近更新 更多