无法在Swift中创建符合协议类型的数组 [英] Can't create an Array of types conforming to a Protocol in Swift

查看:94
本文介绍了无法在Swift中创建符合协议类型的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下协议和符合该协议的类:

I have the following protocol and a class that conforms to it:

protocol Foo{
    typealias BazType

    func bar(x:BazType) ->BazType
}


class Thing: Foo {
    func bar(x: Int) -> Int {
        return x.successor()
    }
}

当我尝试创建foos数组时,出现一个奇怪的错误:

When I try to create an Array of foos, I get an odd error:

var foos: Array<Foo> = [Thing()]

协议Foo只能用作一般约束,因为它具有 自我或相关类型要求.

Protocol Foo can only be used as a generic constraint because it has Self or associated type requirements.

好,因此只有在具有关联的类型要求(确实如此)的情况下才可以使用它,但是由于某种原因,这是一个错误? WTF?!

OK, so it can only be used if it has an associated type requirement (which it does), but for some reason this is an error?? WTF?!

我不确定我是否完全理解编译器要告诉我的内容...

I'm not sure I fully understand what the compiler is trying to tell me...

推荐答案

比方说,如果我们可以将Thing的实例放入数组foos,会发生什么?

Let's say, if we could put an instance of Thing into array foos, what will happen?

protocol Foo {
    typealias BazType

    func bar(x:BazType) -> BazType
}

class Thing: Foo {
    func bar(x: Int) -> Int {
        return x.successor()
    }
}

class AnotherThing: Foo {
    func bar(x: String) -> String {
        return x
    }
}

var foos: [Foo] = [Thing()]

因为AnotherThing也符合Foo,所以我们也可以将其放入foos.

Because AnotherThing conforms to Foo too, so we can put it into foos also.

foos.append(AnotherThing())

现在,我们从foos中随机抓取一个foo.

Now we grab a foo from foos randomly.

let foo = foos[Int(arc4random_uniform(UInt32(foos.count - 1)))]

然后我要调用方法bar,你能告诉我应该向bar发送字符串还是整数?

and I'm going to call method bar, can you tell me that I should send a string or an integer to bar?

foo.bar("foo")foo.bar(1)

雨燕不能.

因此它只能用作一般约束.

So it can only be used as a generic constraint.

什么情况下需要这样的协议?

What scenario requires a protocol like this?

示例:

class MyClass<T: Foo> {
        let fooThing: T?

        init(fooThing: T? = nil) {
                self.fooThing = fooThing
        }

        func myMethod() {
                let thing = fooThing as? Thing // ok
                thing?.bar(1) // fine

                let anotherThing = fooThing as? AnotherThing // no problem
                anotherThing?.bar("foo") // you can do it

                // but you can't downcast it to types which doesn't conform to Foo
                let string = fooThing as? String // this is an error
        }
}

这篇关于无法在Swift中创建符合协议类型的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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