我发现以下代码编译和工作:
func foo(p:UnsafePointer<UInt8>) { var p = p for p; p.memory != 0; p++ { print(String(format:"%2X",p.memory)) } } let str:String = "今日" foo(str)
这打印E4BB8AE697A5,这是今日的有效UTF8表示
据我所知,这是无证的行为.从the document:
When a function is declared as taking a UnsafePointer argument,it can accept any of the following:
- nil,which is passed as a null pointer
- An UnsafePointer,UnsafeMutablePointer,or AutoreleasingUnsafeMutablePointer value,which is converted to UnsafePointer if necessary
- An in-out expression whose operand is an lvalue of type Type,which is passed as the address of the lvalue
- A [Type] value,which is passed as a pointer to the start of the array,and lifetime-extended for the duration of the call
在这种情况下,str不是它们.
我错过了什么吗?
添加:
如果参数类型为UnsafePointer< UInt16>而不起作用
func foo(p:UnsafePointer<UInt16>) { var p = p for p; p.memory != 0; p++ { print(String(format:"%4X",p.memory)) } } let str:String = "今日" foo(str) // ^ 'String' is not convertible to 'UnsafePointer<UInt16>'
即使内部String表示形式是UTF16
let str = "今日" var p = UnsafePointer<UInt16>(str._core._baseAddress) for p; p.memory != 0; p++ { print(String(format:"%4X",p.memory)) // prints 4ECA65E5 which is UTF16 今日 }
这是因为Swift团队从初始启动以来所做的互操作性更改之一,这是正常的 – 您是对的,它似乎尚未成为文档. String的工作原理是UnsafePointer< UInt8>是必需的,以便您可以调用期望一个const char *参数的C函数,而不需要额外的工作.
看看在“shims.h”中定义的C函数strlen:
size_t strlen(const char *s);
在Swift它通过如下:
func strlen(s: UnsafePointer<Int8>) -> UInt
哪些可以使用String调用,而不需要额外的工作:
let str = "Hi." strlen(str) // 3
看看这个答案的修订,看看C-string interop如何随时间而变化:https://stackoverflow.com/a/24438698/59541