您能告诉我为什么无法使用Int32
(或UInt
,UInt8
等)下标Array
的索引吗?以下代码显示了哪些有效和哪些无效的示例:
var buffer = [UInt8]()
buffer.append(0)
buffer[0] = 1 // Valid
buffer[-1] = 1 // Valid :)
var index1:Int = 0
buffer[index1] = 1 // Valid
var index2:Int32 = 0
buffer[index2] = 1 // Invalid
最后一行导致此错误:
不能用索引类型为'Int32'的'[UInt8]'类型的值下标
答案 0 :(得分:3)
在Swift中,Array
符合MutableCollection
的定义,其中Index
定义了关联的MutableCollection.subscript
类型,用于下标。可以在以下subscript(position: Index) -> Element { get set }
签名中看到:
Array
在MutableCollection
的{{1}}实现中,Index
类型被定义为Int
。这就是Array
期望其索引下标具有Int
值的原因。
在您问题的示例中,buffer[0] = 1
起作用的原因是因为Int
(索引类型)和UInt8
(元素类型)都符合ExpressibleByIntegerLiteral
。当类型系统推断索引(和元素)的类型时,它会看到要传递的值要求该类型符合ExpressibleByIntegerLiteral
,并且Array.Index
要求类型为Int
。由于这两个都是可满足的(因为Int
符合ExpressibleByIntegerLiteral
),因此类型系统推断0
是Int
。同样的过程适用于推断1
是UInt8
。
在后面的两个示例中,index1
和index2
变量已分别明确地键入为Int
和Int32
。当将index1
传递到期望Array.subscript
索引的Int
时,类型匹配。但是,当将index2
(类型为Int32
的{{1}}传递给期望Array.subscript
索引的Int
时,类型不匹配。Array
期望{{ 1}}索引和Int
变量显式地键入为index2
,这是另一种类型。没有索引类型的推断,因为这些值不是作为文字传递,而是作为特定类型。