Я обнаружил, что следующий код компилируется и работает:
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 今日
Насколько я знаю, это недокументированное поведение. из документа:
Когда функция объявляется как принимающая аргумент UnsafePointer, она может принимать любое из следующего:
- nil, который передается как нулевой указатель
- Значение UnsafePointer, UnsafeMutablePointer или AutoreleasingUnsafeMutablePointer, которое при необходимости преобразуется в UnsafePointer
- Выражение in-out, операндом которого является lvalue типа Type, который передается как адрес lvalue
- Значение [Тип], которое передается как указатель на начало массива и продлевается на всю продолжительность вызова
В этом случае 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 今日
}