String value to UnsafePointer function parameter behavior
我发现以下代码可以编译并运行:
1 2 3 4 5 6 7 8 9 | 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) |
这将打印
据我所知,这是未记录的行为。 从文档中:
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
在这种情况下,
我想念什么吗?
添加:
如果参数类型为
1 2 3 4 5 6 7 8 9 | 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>' |
即使内部
1 2 3 4 5 | 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团队自首次发布以来就进行了互操作性更改-您说对了,看来它还没有纳入文档范围。
查看在" shims.h"中定义的C函数
1 | size_t strlen(const char *s); |
在Swift中,它是这样实现的:
1 | func strlen(s: UnsafePointer<Int8>) -> UInt |
可以用
1 2 3 | let str ="Hi." strlen(str) // 3 |
查看此答案的修订,以了解C字符串互操作如何随时间变化:https://stackoverflow.com/a/24438698/59541