<div dir="ltr"><div>I agree that the use of `withUnsafeBufferPointer` to get to the contents of an array makes more sense than `withUnsafePointer`, once you discover the concept of a "buffer pointer" (which a new Swift programmer may not do at first).</div><div><br></div>However, I note that the following code:<div><br></div><div> func allZerosUUID() -> String {</div><div><div> var allZeros = [UInt8](repeating: 0, count: 32)</div><div> return NSUUID(uuidBytes: &allZeros)</div><div> }</div></div><div><br></div><div>also compiles without error and returns the intended value. This appears to be supported by the "Constant Pointers" section of the "Interacting with C APIs" chapter of "Using Swift with Cocoa and Objective-C": "When a function is declared as taking an `UnsafePointer<Type>` argument, it can accept ... a `[Type]` value, which is passed as a pointer to the start of the array."</div><div><br></div><div>I suspect the availability of `&array` in this context, coupled with an awareness of the existence of `withUnsafePointer(to:)`, is what led my co-worker down the wrong road (and to a puzzling error message); but since we have now discovered two more appropriate ways to write the code in question, perhaps it's not worth worrying about too much.</div><div><br></div><div>Thanks to everyone for the discussion.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 1, 2017 at 7:36 PM, Hooman Mehr <span dir="ltr"><<a href="mailto:hooman@mac.com" target="_blank">hooman@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Your co-worker needs to get passed the learning curve of these “unsafe” APIs and note that Swift arrays are complex data structures. &allZeros does not give you a pointer to a bunch of zero bytes, but a pointer to a struct that contains the private implementation details of allZeros array. <div><br></div><div>Here is the correct way to do it:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">func</span><span style="font-variant-ligatures:no-common-ligatures"> allZerosUUID() -> </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">String</span><span style="font-variant-ligatures:no-common-ligatures"> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">let</span><span style="font-variant-ligatures:no-common-ligatures"> allZeros = [</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">UInt8</span><span style="font-variant-ligatures:no-common-ligatures">](repeating: </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8">0</span><span style="font-variant-ligatures:no-common-ligatures">, count: </span><span style="font-variant-ligatures:no-common-ligatures;color:#272ad8">32</span><span style="font-variant-ligatures:no-common-ligatures">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">return</span><span style="font-variant-ligatures:no-common-ligatures"> allZeros.</span><span style="font-variant-ligatures:no-common-ligatures;color:#3e1e81">withUnsafeBufferPoint<wbr>er</span><span style="font-variant-ligatures:no-common-ligatures"> { </span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">NSUUID</span><span style="font-variant-ligatures:no-common-ligatures">(uuidBytes: $0.</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">baseAddress</span><span style="font-variant-ligatures:no-common-ligatures">).</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">uuidString</span><span style="font-variant-ligatures:no-common-ligatures"> }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">}</span></div></div><div><span style="font-variant-ligatures:no-common-ligatures"><br></span></div><div><br></div><div><div><blockquote type="cite"><div><div class="h5"><div>On Mar 1, 2017, at 2:35 PM, Russell Finn via swift-users <<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>> wrote:</div><br class="m_-8311670139065548302Apple-interchange-newline"></div></div><div><div><div class="h5"><div dir="ltr">Thanks to Joe and Quinn for their answers. I have a related followup — a co-worker learning Swift wrote the following function:<br><div><br> func allZerosUUID() -> String {<br> var allZeros = [UInt8](repeating: 0, count: 32)<br> return withUnsafePointer(to: &allZeros) { zerosPtr in<br> return NSUUID(uuidBytes: zerosPtr).uuidString<br> }<br> }<br><br>but was puzzled that Xcode 8.2.1 gave an error "Cannot convert value of type 'UnsafePointer<_>' to expected argument type 'UnsafePointer<UInt8>!'" on the line with the NSUUID initializer. Their expectation was that `zerosPtr` would be of type `UnsafePointer<UInt8>` because `allZeros` is of type `[UInt8]`. </div><div><br></div><div>They discovered that they could work around this by adding a call to `withMemoryRebound`:<br><br> func allZerosUUID() -> String {<br> var allZeros = [UInt8](repeating: 0, count: 32)<br> return withUnsafePointer(to: &allZeros) { zerosPtr in<br> zerosPtr.withMemoryRebound(to: UInt8.self, capacity: allZeros.count) { zerosPtr in<br> return NSUUID(uuidBytes: zerosPtr).uuidString<br> }<br> }<br> }<br><br>but felt that this should be unnecessary. Perhaps I'm missing something simple, but I was unable to explain this compiler behavior; can anyone on the list do so?</div><div><br></div><div>(Yes, I did point out that they could pass `&allZeros` directly to `NSUUID(uuidBytes:)`.)<br></div><div class="gmail_extra"><div class="gmail_quote"><br></div><div class="gmail_quote">Thanks — Russell</div><div class="gmail_quote"><br></div></div></div></div></div><span class="">
______________________________<wbr>_________________<br>swift-users mailing list<br><a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br></span></div></blockquote></div><br></div></div></blockquote></div><br></div>