Swift结构协议不能按预期工作

时间:2015-12-24 19:35:24

标签: swift

遵循游乐场准备好的代码;)

protocol Prot {
    static func instanceArray() -> [Self]
}

struct A {
    init() {
        // Do something
    }
}

extension A: Prot {
    static func instanceArray() -> [A] {
        return [A(), A()]
    }
}

func work() -> [Prot] {
    return A.instanceArray()
}

编译器将在return A.instanceArray()处抛出错误:无法将类型[A]的返回表达式转换为返回类型[Prot]

为什么即使A实现协议Prot,编译器也无法转换这些类型? 我知道解决方法是将instanceArray()的返回类型更改为[Prot],但我不太喜欢这种解决方案。 这是编译器错误还是功能?

2 个答案:

答案 0 :(得分:2)

如果你必须

,可以绕过它
func work() -> [Prot] {
    return A.instanceArray().map{ $0 as Prot }
}

答案 1 :(得分:1)

如果我们消除了示例中不需要的所有额外内容,将会更容易看到发生了什么。所以,请考虑一下:

protocol Prot {}
struct A : Prot {}

let arr = [A(), A()] // 1: ok
let arr2 = [A(), A()] as [Prot] // 2: ok
let arr3 = arr as [Prot] // 3: compile error

那么问题是,为什么[2]合法但[3]不合法?区别在于我们允许形成 A个实例的数组并将其键入为[Prot],但我们不允许强制转换现有的数组变量已经输入为[A]的{​​{1}}。

如果您愿意,可以将此称为Swift的错误或限制,并且您在提交错误报告时肯定是合理的,但无论如何,这是一个众所周知的缺点,与协议的事实有关只是不完全成熟的类型。