Swift泛型类型转换

8
我有一个通用类,其中包含一个泛型类型的数组。现在我想根据数组中的类进行一些操作。我有两个类:Person和House(没有继承关系)。但是这段代码不起作用:
let allValues = [T]()
if allValues[0] is Person { 
     let values = (allValues as [Person])
}

但是这样做行不通,因为T并不等于'Person'。我该怎么办?谢谢任何帮助。

2个回答

5
您不能这样做(或者至少不会这么简单,需要通过一些相当曲折且不可取的方式)。您认为T更像是Any类型,这是一个可以容纳任何其他类型并且可以使用as(或者可能更适合使用as?)在运行时转换回真实类型的类型。

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

您实际上要实现的基本功能是什么? 人和房屋非常不同,因此您真的需要编写一个可以通用操作它们的函数吗?


1
我想根据一些数值绘制一些图形,但我突然想到我可以实现一个协议,不是吗? - borchero
1
听起来更像是你想要的。 - Airspeed Velocity

4

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

不过,你可以使用以下语法执行你所要求的转换:

let values = allValues as Any as [Person]

现在我看到了两个问题:
  1. 你的条件语句会崩溃,因为数组allValues没有包含任何元素,而你正在访问第一个不存在的元素。
  2. allValues数组可能在第一个位置包含一个Person对象,在第二个位置包含其他类型的对象。这使得在仅评估第一个元素之后进行强制转换非常危险。

    例如:

    class LifeForm {}

    class Person : 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]
        }
    }
}

重要提示:我提供这段代码只是为了展示语法。我不喜欢这种方法(再次,使用协议会更好),因为Things类包含特定于Person的逻辑。 理想情况下,Things不应该知道任何关于Person的信息,因为Things是一个通用类。


1
好的,你说得对,这看起来很糟糕 - 我会使用协议,但还是谢谢你:] - borchero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接