我们知道String.utf16提供了代码单位,而String.unicodeScalars提供了标量。
如果我们通过删除一些元素等来操纵codeunits和unicodeScales,是否有办法构造回结果字符串?
Swift 2.1更新:
您可以使用StringUTF-16字符数组创建一个
String
public init(utf16CodeUnits: UnsafePointer<unichar>, count: Int)
初始化程序。例:
let str = "H€llo 😄" // String to UTF16 array: let utf16array = Array(str.utf16) print(utf16array) // Output: [72, 8364, 108, 108, 111, 32, 55357, 56836] // UTF16 array to string: let str2 = String(utf16CodeUnits: utf16array, count: utf16array.count) print(str2) // H€llo 😄
先前的答案:
没有任何“内置”(据我所知),但是您可以使用UTF16提供一种decode()方法的结构:
UTF16
decode()
extension String { init?(utf16chars:[UInt16]) { var str = "" var generator = utf16chars.generate() var utf16 : UTF16 = UTF16() var done = false while !done { let r = utf16.decode(&generator) switch (r) { case .EmptyInput: done = true case let .Result(val): str.append(Character(val)) case .Error: return nil } } self = str } }
例:
let str = "H€llo 😄" // String to UTF16 array: let utf16array = Array(str.utf16) print(utf16array) // Output: [72, 8364, 108, 108, 111, 32, 55357, 56836] // UTF16 array to string: if let str2 = String(utf16chars: utf16array) { print(str2) // Output: H€llo 😄 }
稍微 通用一点 ,您可以定义一个方法,该方法使用给定的编解码器从代码点的数组(或任何序列)创建一个字符串:
extension String { init?<S : SequenceType, C : UnicodeCodecType where S.Generator.Element == C.CodeUnit> (codeUnits : S, var codec : C) { var str = "" var generator = codeUnits.generate() var done = false while !done { let r = codec.decode(&generator) switch (r) { case .EmptyInput: done = true case let .Result(val): str.append(Character(val)) case .Error: return nil } } self = str } }
然后从UTF16转换完成
if let str2a = String(codeUnits: utf16array, codec: UTF16()) { print(str2a) }
这是另一种可能的解决方案。虽然先前的方法是“纯Swift”,但该方法使用Foundation框架以及在NSString和Swift 之间的自动桥接String:
NSString
extension String { init?(utf16chars:[UInt16]) { let data = NSData(bytes: utf16chars, length: utf16chars.count * sizeof(UInt16)) if let ns = NSString(data: data, encoding: NSUTF16LittleEndianStringEncoding) { self = ns as String } else { return nil } } }