Swift generic type cast

非 Y 不嫁゛ 提交于 2019-12-10 14:09:06

问题


I have a generic class where I have an array of generic types. No I want to do some operations based on the class in the array. I have 2 classes: Person and House (no Inheritance). But this code doesn't work:

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

But this doesn't work as T is not identical to 'Person'. What do I have to do? Thanks for any help.


回答1:


I agree with Oliver Borchert and Airspeed Velocity: this kind of problem should be addressed using a protocol.

However you can perform the cast you asked about using this syntax:

let values = allValues as Any as [Person]

Now I see 2 problems:

  1. Your IF will crash because your array allValues contains 0 elements and you are accessing the first one (that does not exist).
  2. allValues could have a Person at the first element and something else at the second position. This makes dangerous a cast after having evaluated only the first element.

    Example

    class LifeForm {}

    class Person : LifeForm {}

    With T equals to LifeForm.

I think the following version is safer because you are directly evaluating the type 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]
        }
    }
}

Important: I provided this code just to show the syntax. I don't like this abborach (again, a Protocol would be better) because the class Things contains logic specific to Person. Ideally Things should know nothing about Person because Things is a generic class.




回答2:


You can’t do this (or at least, not without jumping through some pretty tortuous and inadvisable hoops). You are thinking of T more like the Any type, which is a type that can hold any other type and that you can turn back into the real type with as (or probably preferably as?) at runtime.

But generics don’t work like this. Within your code, the generic T will be replaced with a real type at compile time, and that type might not be a Person. What would the code above do if that were the case?

What is the underlying functionality you’re actually trying to achieve? People and houses are very different so do you really need to write a function that operates generically on both of them?



来源:https://stackoverflow.com/questions/27591366/swift-generic-type-cast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!