<aside> 👣 使用 some 来表示不透明类型,需要注意的是,不透明类型需要保证一致性,即函数内部不能返回多个不同类型的值。

</aside>

返回不透明类型

不透明类型和协议类型的区别

<aside> 🍼 如上所述,不透明类型需要保持类型一致性,而协议类型则不需要,只要是遵循协议的类型即可。下面的代码因为返回的是协议类型,所以不会报错,但若改为不透明类型则不可,因为第一个返回值 shape 的类型是 Square,而第二个返回值的类型是 FlippedShape

</aside>

func protoFlip<T: Shape>(_ shape: T) -> Shape {
    if shape is Square {
        return shape
    }

    return FlippedShape(shape: shape)
}

<aside> 💭 使用协议类型作为返回值虽然具有灵活性,但是会发生类型擦除,同时无法使用嵌套。

</aside>

<aside> ❓ 有关联类型的协议不能作为返回类型。

</aside>

protocol Container {
    associatedtype Item
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}
extension Array: Container { }

// 错误:有关联类型的协议不能作为返回类型。
func makeProtocolContainer<T>(item: T) -> Container {
    return [item]
}

// 错误:没有足够多的信息来推断 C 的类型。
func makeProtocolContainer<T, C: Container>(item: T) -> C {
    return [item]
}