Swift:将Foo <string>转换为Foo <any>

时间:2015-08-10 15:06:40

标签: ios swift generics casting

这是我的代码

class Foo<T> {

}

class Main {
    static func test() {
        var foo: Foo<Any>

        var bar = Foo<String>()
        //Do all my stuff with foo necessitating String

        foo = bar
    }
}

当我尝试分配foo = bar时,我收到错误Cannot assign a value of type Foo<String> to a value of type Foo<Any>。 我不明白为什么我得到这个错误,因为String符合Any。 如果我使用Array做同样的事情,我没有任何错误

static func test() {
        var foo: Array<Any>

        var bar = Array<String>()
        //Do all my stuff with foo necessitating String

        foo = bar
    }

有谁知道我的代码出了什么问题? 感谢

2 个答案:

答案 0 :(得分:2)

数组和字典是内置此类行为的特殊类型。但是,这不适用于自定义泛型类型。类型Foo<Any>不是Foo<String>的超类型(或者在这种情况下是超类),即使AnyString的超类型。因此,您无法相互分配这些类型的变量。

根据您的具体情况,Swift Cast Generics Type中列出的解决方案可能对您有用。当Foo包装类型T的值时,您可以添加一个通用构造函数,用于转换来自Foo的不同类型实例的值。

class Foo<T> {
    var val: T

    init(val: T) {
        self.val = val
    }

    init<O>(other: Foo<O>) {
        self.val = other.val as! T
    }
}

class Main {
    static func test() {
        var foo: Foo<Any>

        var bar = Foo<String>(val: "abc")
        //Do all my stuff with foo necessitating String

        foo = Foo<Any>(other: bar)
    }
}

答案 1 :(得分:2)

通过添加定义如何从类型O转换为类型T

的能力,我对@hennes的答案进行了改进
class Foo<T> {
    var val: T

    init(val: T) {
        self.val = val
    }

    init<O>(other:Foo<O>, conversion:(O) -> T) {
        self.val = conversion(other.val)
    }
}

class Main {
    static func test() {
        var foo: Foo<Int>

        var bar = Foo<String>(val: "10")
        //Do all my stuff with foo necessitating String

        foo = Foo<Int>(other: bar, conversion: {(val) in
            return Int(val.toInt()!)
        })
        print(foo.val) //prints 10
        print(foo.val.dynamicType) //prints Swift.Int
    }
}

这使您能够在两种不支持相互投射的类型之间进行转换。此外,它在转换非法时给出编译器警告,而不是由于强制转换而导致崩溃。

不知道为什么1或&gt; 1行封闭的编译器警告存在差异,但有。

1行关闭的编译器警告错误 useless compiler warning

2行关闭的良好编译器警告 enter image description here