Array<T> or Slice<T> struct type understanding structure

268 Views Asked by At

While Array struct def is:

struct Array<T> : MutableCollection, Sliceable {
    typealias Element = T
    var startIndex: Int { get }
    var endIndex: Int { get }
    subscript (index: Int) -> T
    func generate() -> IndexingGenerator<[T]>
    typealias SliceType = Slice<T>
    subscript (subRange: Range<Int>) -> Slice<T>
}

while MutableCollection is:

protocol MutableCollection : Collection {
    subscript (i: Self.IndexType) -> Self.GeneratorType.Element { get set }
}

then Collection:

protocol Collection : Sequence {
    subscript (i: Self.IndexType) -> Self.GeneratorType.Element { get }
}

and then Sequence:

protocol Sequence {
    typealias GeneratorType : Generator
    func generate() -> GeneratorType
}

and Sliceable:

protocol Sliceable {
    typealias SliceType
    subscript (_: Range<Self.IndexType>) -> SliceType { get }
}

(Slice is almost equivalent to Array)

Where is the backstore ?

1

There are 1 best solutions below

1
On

It's private. It used to be exposed as ArrayBuffer, but they removed that from the public headers (in beta 4 I believe). They do still (indirectly) expose the existence of _ContiguousArrayBuffer in beta 4.

The natural question is "why do you want to know?" The storage specifics are not a part of the interface of Array, so they're subject to change. Keep in mind that Array is independent of ContiguousArray, so almost anything you'd think you wanted to do with the backing storage probably wouldn't be safe anyway (since it's not even promised to be contiguous).

All that fancy-stuff said, you do in fact have access to something that is promised to look like the backing store. That's withUnsafePointerToElements. This will hand you a pointer that you are allowed to do pointer math on and get elements in the array (just like in C). (This method is in the header, but not the docs, so it may not survive the betas.)

You're also allowed to pass &arrayT to a C function that takes a *T, and it'll make it look like there really is a contiguous block of memory there. That's in the docs, so it's even more likely to stay true.