无法在Swift中创建符合协议的类型数组

cfi*_*her 17 protocols associated-types swift

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

protocol Foo{
    typealias BazType

    func bar(x:BazType) ->BazType
}


class Thing: Foo {
    func bar(x: Int) -> Int {
        return x.successor()
    }
}
Run Code Online (Sandbox Code Playgroud)

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

var foos: Array<Foo> = [Thing()]
Run Code Online (Sandbox Code Playgroud)

Protocol Foo只能用作通用约束,因为它具有Self或相关类型要求.

好的,所以它只能在它有一个相关的类型要求(它确实如此)时使用,但由于某种原因这是一个错误?WTF?

我不确定我完全理解编译器试图告诉我的内容......

yli*_*x81 16

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

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()]
Run Code Online (Sandbox Code Playgroud)

因为也AnotherThing符合Foo,所以我们也可以把它放进去foos.

foos.append(AnotherThing())
Run Code Online (Sandbox Code Playgroud)

现在,我们抓住一个foofoos随机.

let foo = foos[Int(arc4random_uniform(UInt32(foos.count - 1)))]
Run Code Online (Sandbox Code Playgroud)

我打算调用方法bar,你能告诉我我应该发送一个字符串或整数bar吗?

foo.bar("foo") 要么 foo.bar(1)

斯威夫特不能.

所以它只能用作通用约束.

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

例:

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
        }
}
Run Code Online (Sandbox Code Playgroud)