问题描述
我发现以下代码可以编译并运行:
I found the following code compiles and works:
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
,这是 今日
据我所知,这是未记录的行为.来自 文档:
As far as I know, this is undocumented behavior. from the document:
当函数被声明为采用 UnsafePointer 参数时,它可以接受以下任何一种:
- nil,作为空指针传递
- UnsafePointer、UnsafeMutablePointer 或 AutoreleasingUnsafeMutablePointer 值,必要时转换为 UnsafePointer
- 一个输入输出表达式,其操作数是 Type 类型的左值,作为左值的地址传递
- 一个 [Type] 值,作为指向数组开头的指针传递,并在调用期间延长生命周期
在这种情况下,str
不属于它们.
In this case, str
is non of them.
我错过了什么吗?
添加:
如果参数类型为UnsafePointer
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
Even though the internal String
representation is 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
的地方,这样您就可以调用需要 const char *
参数的 C 函数,而无需太多额外的工作.
This is working because of one of the interoperability changes the Swift team has made since the initial launch - you're right that it looks like it hasn't made it into the documentation yet. String
works where an UnsafePointer<UInt8>
is required so that you can call C functions that expect a const char *
parameter without a lot of extra work.
看C函数strlen
,定义在shims.h"中:
Look at the C function strlen
, defined in "shims.h":
size_t strlen(const char *s);
在 Swift 中是这样的:
In Swift it comes through as this:
func strlen(s: UnsafePointer<Int8>) -> UInt
可以用 String
调用而无需额外工作:
Which can be called with a String
with no additional work:
let str = "Hi."
strlen(str)
// 3
查看此答案的修订,了解 C 字符串互操作如何随时间变化:https://stackoverflow.com/a/24438698/59541
Look at the revisions on this answer to see how C-string interop has changed over time: https://stackoverflow.com/a/24438698/59541
这篇关于UnsafePointer<UInt8> 的字符串值函数参数行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!