为什么不应该用序列对象创建自定义结构?

时间:2018-07-16 05:36:43

标签: swift generics

我希望使用类型推断使用序列对象创建我的结构。喜欢:

var words: Buffer = ["generics", "ftw"] // type should be Buffer<String>

所以我创建了这样的结构

struct Buffer<Element> {
init<S>(_ s: S) where Element == S.Element, S : Sequence {
}}

我只是编写了上面的代码来测试通用的init。

当我创建这样的结构时,代码起作用:

var words = Buffer(["generics", "ftw"])

但是我不能创建这样的结构:

var words: Buffer = ["generics", "ftw"]

var words: Buffer<String> = ["generics", "ftw"]

编译器向我抱怨:

  

上下文类型'Buffer'不能与数组文字一起使用

我认为我向编译器提供了足够的信息,

嘿,编译器,您将收到一个序列。而我提到的元素是Sequence的元素。

我想念什么?

1 个答案:

答案 0 :(得分:0)

要使用语法糖,必须采用ExpressibleByArrayLiteral协议,这将使struct能够使用数组文字进行初始化。

extension Buffer: ExpressibleByArrayLiteral {
    typealias ArrayLiteralElement = Element

    init(arrayLiteral: Element...) {
        self.init(arrayLiteral)
    }
}

添加此扩展名后,代码类似

var words: Buffer = ["generics", "ftw"]

var words: Buffer<String> = ["generics", "ftw"]

将编译。

请注意,尽管它是用数组文字初始化的,但这并不是 表示words是一个数组。如果将单词variable分配给Array类型的变量,则代码将无法编译,反之亦然。另外,请注意,如果您未在变量声明中推断类型Buffer,它将被推断为Array,因此您必须 在其中包含Buffer可变脱纤。