Преобразование UInt32 (UTF-32) в строку в Swift
У меня есть массив значений UInt32. Я хотел бы преобразовать этот массив в String
.
Это не работает:
let myUInt32Array: [UInt32] = [72, 101, 108, 108, 111, 128049]
let myString = String(myUInt32Array) // error
let myString = String(stringInterpolationSegment: myUInt32Array) // [72, 101, 108, 108, 111, 128049] (not what I want)
Эти сообщения SO показывают UTF8
и UTF16
:
Ответы
Ответ 1
UnicodeScalar
- это псевдоним типа UInt32
. Поэтому добавьте значения UInt32
в UnicodeScalar
, а затем добавьте их в String
.
let myUInt32Array: [UInt32] = [72, 101, 108, 108, 111, 128049]
var myString: String = ""
for value in myUInt32Array {
if let scalar = UnicodeScalar(value) {
myString.append(Character(scalar))
}
}
print(myString) // Hello🐱
Ответ 2
(Ответ был обновлен для Swift 4 и позже.)
Используя Swift типа Data
и String
это можно сделать как
let myUInt32Array: [UInt32] = [72, 101, 108, 108, 111, 128049, 127465, 127466]
let data = Data(bytes: myUInt32Array, count: myUInt32Array.count * MemoryLayout<UInt32>.stride)
let myString = String(data: data, encoding: .utf32LittleEndian)!
print(myString) // Hello🐱🇩🇪
Принудительное развертывание используется здесь, потому что преобразование из кодовых точек UTF-32 в строку не может завершиться неудачей.
Вы можете определить расширение String
для вашего удобства
extension String {
init(utf32chars:[UInt32]) {
let data = Data(bytes: utf32chars, count: utf32chars.count * MemoryLayout<UInt32>.stride)
self = String(data: data, encoding: .utf32LittleEndian)!
}
}
и использовать его как
let myUInt32Array: [UInt32] = [72, 101, 108, 108, 111, 128049, 127465, 127466]
let myString = String(utf32chars: myUInt32Array)
print(myString) // Hello🐱🇩🇪
И просто для полноты, универсальный конвертер из fooobar.com/info/49782/...
extension String {
init?<C : UnicodeCodec>(codeUnits:[C.CodeUnit], codec : C) {
var codec = codec
var str = ""
var generator = codeUnits.makeIterator()
var done = false
while !done {
let r = codec.decode(&generator)
switch (r) {
case .emptyInput:
done = true
case .scalarValue(let val):
str.unicodeScalars.append(val)
case .error:
return nil
}
}
self = str
}
}
может использоваться с входами UTF-8, UTF-16 и UTF-32. В вашем случае это было бы
let myUInt32Array: [UInt32] = [72, 101, 108, 108, 111, 128049, 127465, 127466]
let myString = String(codeUnits: myUInt32Array, codec : UTF32())!
print(myString) // Hello🐱🇩🇪