如何在Swift中将[Int8]转换为[UInt8]
我有一个只包含字符的缓冲区
let buffer: [Int8] = .... 然后我需要将它传递给一个以[UInt8]为参数的函数进程. func process(buffer: [UInt8]) { // some code } 将[Int8]缓冲区传递给[Int8]的最佳方法是什么?我知道下面的代码可以工作,但在这种情况下,缓冲区只包含一堆字符,并且不必使用map等函数. process(buffer.map{ x in UInt8(x) }) // OK process([UInt8](buffer)) // error process(buffer as! [UInt8]) // error 我正在使用Xcode7 b3 Swift2. 解决方法
我大致同意你应该坚持使用map的其他答案,但是,如果你的数组非常庞大,并且创建一个完整的第二个缓冲区只是为了转换为相同的位模式真的很痛苦,你可以这样做:
// first,change your process logic to be generic on any kind of container func process<C: CollectionType where C.Generator.Element == UInt8>(chars: C) { // just to prove it's working... print(String(chars.map { UnicodeScalar($0) })) } // sample input let a: [Int8] = [104,101,108,111] // ascii "Hello" // access the underlying raw buffer as a pointer a.withUnsafeBufferPointer { buf -> Void in process( UnsafeBufferPointer( // cast the underlying pointer to the type you want start: UnsafePointer(buf.baseAddress),count: buf.count)) } // this prints [h,e,l,o] 注意withUnsafeBufferPointer意味着它所说的.这是不安全的,如果你弄错了你可以破坏记忆(尤其要小心计数).它基于您的外部知识工作,例如,如果任何整数是负数,那么您的代码不会介意它们成为损坏的无符号整数.你可能知道,但是Swift类型的系统不能,所以它不会允许它而不诉诸不安全的类型. 也就是说,上述代码是正确的并且在规则范围内,如果您需要性能优势,这些技术是合理的.除非你处理大量的数据或编写一个你称之为无数次的库,否则你几乎肯定不会. 值得注意的是,在某些情况下,数组实际上并未由连续缓冲区支持(例如,如果它是从NSArray强制转换的),在这种情况下,调用.withUnsafeBufferPointer将首先将所有元素复制到连续的数组中.此外,Swift数组是可扩展的,因此底层元素的副本通常随着数组的增长而发生.如果性能绝对至关重要,您可以考虑使用UnsafeMutablePointer分配自己的内存,并使用UnsafeBufferPointer使用固定大小的样式. 对于一个幽默但绝对不在你不应该实际使用的规则示例中,这也将起作用: process(unsafeBitCast(a,[UInt8].self)) 值得注意的是,这些解决方案与a.map {UInt8($0)}不同,因为如果你传递一个负整数,后者将在运行时陷阱.如果有可能,您可能需要先过滤它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |