Swift Generics&上溯造型 [英] Swift Generics & Upcasting

查看:112
本文介绍了Swift Generics&上溯造型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于Swift泛型的简单问题。问题是我试图存储一个变量,它将一个泛型作为参数,但无法将它转换为受其限制的类型。最好用一个简短的例子来解释:

  class Foo {} 

class Thing< T:Foo> ; {
func produceBar() - > Bar {
return Bar(aThing:self as!Thing< Foo>)
}
}

class Bar {
var thing:Thing< Foo> ;

init(var aThing:Thing< Foo>){
self.thing = aThing
}
}

上面的代码产生错误:从Thing< T>转换为不相关的类型Thing< Foo>总是失败 $ b

它不应该失败,因为T仅限于Foo的子类吗?我必须误解Swift中泛型的工作方式,任何指导或帮助都将不胜感激!

解决方案

Swift泛型不是协变的。也就是说,错误所说的是:你不能自动说< Basket< Apple> 是一种 Basket< Fruit> / code>即使 Apple 是一种 Fruit





  class Fruit {} 
class Apple:Fruit {}
class Orange:水果{}

类篮子< T:水果> {
private var items:[T]
func add(item:T){
items.append(item)
}
init(){}


func addItem< T:Fruit>(var basket:Basket< T>,item:T){
basket.add(item)
}

让篮子:篮子< Apple> =篮子()

addItem(篮子为篮子<水果> ;,橙色())

如果篮子< Apple> 被视为篮子< Fruit> ,那么这将是合法的代码,并且I我们可以在一篮子苹果中加入橙子。

I've got a quick question regarding generics in Swift. The problem is I'm trying to store a variable that takes a generic as a parameter, but am unable to cast it up to the type it is restricted by. It's best explained in a short example:

class Foo { }

class Thing<T: Foo> {
    func produceBar() -> Bar {
        return Bar(aThing: self as! Thing<Foo>)
    }
}

class Bar {
    var thing: Thing<Foo>

    init(var aThing: Thing<Foo>) {
        self.thing = aThing
    }
}

The code above produces the error: "Cast from Thing<T> to unrelated type Thing<Foo> always fails"

Shouldn't it never fail, since T is restricted to being a subclass of Foo? I must be misunderstanding the way generics work in Swift, any guidance or help would be much appreciated!

解决方案

Swift generics are not covariant. That is to say, exactly what the error says: you can't automatically say a Basket<Apple> is a kind of Basket<Fruit> even if Apple is a kind of Fruit. There is good reason for this.

Consider the following code:

class Fruit {}
class Apple: Fruit {}
class Orange: Fruit {}

class Basket<T: Fruit> {
    private var items: [T]
    func add(item: T) {
        items.append(item)
    }
    init() {}
}

func addItem<T: Fruit>(var basket: Basket<T>, item: T) {
    basket.add(item)
}

let basket:Basket<Apple> = Basket()

addItem(basket as Basket<Fruit>, Orange())

This would be legal code if Basket<Apple> were considered a Basket<Fruit>, and I'd be allowed to add an orange to a basket of apples.

这篇关于Swift Generics&amp;上溯造型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆