I want to access an existing array of UInt64 as if it is an array of Int8. Key requirement is efficiency - I don't want to copy or reallocate the data, just have direct access. I don't want side effects (for example I want to be able to continue to use the uint64Array after this block of code has executed, was reading about rebinding having undefined side effects.)
I tried doing this with Swift 4.2:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.withUnsafeMutableBufferPointer() {
uint64Pointer in
uint64Pointer.withMemoryRebound(to: Int8.self) { // <- Error occurs here.
int8Pointer in
int8Pointer[0] = 1
int8Pointer[1] = 2
int8Pointer[2] = 3
int8Pointer[3] = 4
}
}
However I get a Fatal Error at runtime on the following line:
uint64Pointer.withMemoryRebound(to: Int8.self) {
Is this the right approach? If so, why am I getting the Fatal Error?
I think the problem is that you can't bind to a different type directly as per this note in the docs:
Only use this method to rebind the buffer’s memory to a type with the same size and stride as the currently bound Element type. To bind a region of memory to a type that is a different size, convert the buffer to a raw buffer and use the bindMemory(to:) method.
If bytes is what you're after then the quickest route is:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.withUnsafeMutableBytes { x in
x[0] = 1
x[1] = 2
x[3] = 3
x[4] = 4
}
If you have another type you'd like to use you can do it like this:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.withUnsafeMutableBufferPointer() {
uint64Pointer in
let x = UnsafeMutableRawBufferPointer(uint64Pointer).bindMemory(to: Int32.self)
x[0] = 1
x[1] = 2
x[3] = 3
x[4] = 4
}