1

We all know that [UInt8] type is not equal UnsafePointer<UInt8>,

But why can I pass [UInt8] type to UnsafePointer<UInt8> type parameter:

let p = UnsafeMutablePointer<UInt8>.allocate(capacity: 4)
p.initialize(repeating: 0, count: 4)

let ary:[UInt8] = [1,2,3,4]
p.assign(from: ary, count: 4)  // It's OK, why?

As shown above,p.assign method frist parameter type is UnsafePointer<T>, but It's OK when I pass the type [UInt8]...

Why is that? Thanks! ;)

hopy
  • 559
  • 3
  • 18

1 Answers1

2

It's just a shortcut.

An unsafe pointer is effectively a C array: what we are pointing at is the first address of a contiguous block of memory. Therefore Swift gives you some nice help for when you have a Swift array from which you want to write to the memory: this Swift array is nothing whatever like a C array, but nevertheless, you can pass a pointer to the Swift array or even the Swift array itself, including an array literal, and Swift will just do the right thing.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • I'd argue a C array is just an unsafe pointer ;) – Alexander Jun 18 '21 at 03:09
  • @Alexander Surprisingly, the other day I was trying to call some of the C code I wrote from Swift, and arrays (`int foo[10];`) got bridged into tuples! And some of the really long C arrays are entirely inaccessible from Swift for some reason (exceeds the maximum number of tuple elements probably). – Sweeper Jun 18 '21 at 03:15
  • @Sweeper Haha yeah, it's really annoying. Swift doesn't really have the ability to express iteration over a tuple like that, which makes it worse. On the upside, tuples with homogeneous types are guaranteed to be stored contiguously in memory, [so you can use `Unsafe(Mutable)BufferPointer` to handle them like a `Collection`](https://stackoverflow.com/a/67744915/3141234). – Alexander Jun 18 '21 at 03:27
  • @matt Thanks! But why I can't do this: if let p1 = ary as? UnsafePointer {/*...*/} , It's tell me: Cast from '[UInt8]' to unrelated type 'UnsafePointer' always fails! – hopy Jun 18 '21 at 05:47
  • Because they _are_ unrelated. Did you read my answer? "Swift array is nothing whatever like a C array" But when you pass an array where a pointer is expected, magic happens behind the scenes, as a convenience. – matt Jun 18 '21 at 06:01
  • @matt I got it! – hopy Jun 18 '21 at 06:15