Could you tell me why it's not possible to use a Int32
(or UInt
, UInt8
, etc.) index to subscript Array
? The following code show examples of what work and what doesn't work:
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
The last line results in this error:
Cannot subscript a value of type '[UInt8]' with an index of type 'Int32'
In Swift, Array
conforms to—among other things—MutableCollection
which defines an associated Index
type, which is used for subscripting. This can be seen in the following MutableCollection.subscript
signature:
subscript(position: Index) -> Element { get set }
In the Array
implementation of MutableCollection
the Index
type is defined as Int
. This is why Array
expects Int
values for its indexed subscript.
In the examples in your question, the reason why buffer[0] = 1
works is because both Int
(the index type) and UInt8
(the element type) conforms to ExpressibleByIntegerLiteral
. When the type system infers the types of the index (and the element) it sees that the value being passed requires the type to conform to ExpressibleByIntegerLiteral
and that Array.Index
requires the type to be Int
. Since both of these are satisfiable (because Int
conforms to ExpressibleByIntegerLiteral
), the type system infers that the 0
is an Int
. The same process applies to inferring that the 1
is a UInt8
.
In the later two examples the index1
and index2
variables have been explicitly typed as Int
and Int32
respectively. When passing index1
to Array.subscript
which expects an Int
index, the types match. However, when passing index2
(which is of type Int32
to Array.subscript
which expects an Int
index, there is a type mismatch. Array
expects an Int
index and the index2
variable is explicitly typed as Int32
which is a different type. There is no inference of the index type because these values aren't passed as literals, but rather as variables with a specific type.