将 [type_a] 转换为 [type_b]

Posted

技术标签:

【中文标题】将 [type_a] 转换为 [type_b]【英文标题】:Convert [type_a] to [type_b] 【发布时间】:2017-04-28 06:55:48 【问题描述】:

我实际上已经在 *** 和其他地方广泛地搜索了这个。 大多数问题是关于 [UInt8] 到 String 或 [UInt8] 到 type_a(不是数组)。

为了澄清,我想采用 type_a 的数组。获取它的指针并告诉 swift 将 type_b (size_of) 的下 n 次迭代视为 type_b 的数组。

我尝试了https://***.com/a/26954091/5276890 的变体,但没有成功。那里的评论让我去了https://***.com/a/42255468/5276890。 withMemoryRebound 似乎是正确的方法,但我找不到正确的调用。

这是我正在做的将 [UInt8] 转换为 [UInt32.bigEndian] 的示例代码,以澄清并以防万一它有用(不太可能)

    var intData = [UInt32]()
    let M = UInt32(256*256*256)
    var m = M
    var bigE:UInt32 = 0
    for i in 0..<data.count 
        bigE += UInt32(data[i]) * m
        if m == 1 
            intData.append(bigE)
            bigE = 0
            m = M
         else 
            m = m/256
        
    

我不得不承认我永远无法弄清楚整个闭包+withUnsafe* 语法,并且主要使用在线模式并对其进行修改。只要语言作者决定并确定一种特定的语法,我就会花时间学习这个:(+rant>

【问题讨论】:

【参考方案1】: 使用withUnsafeBufferPointer 获取指向元素的指针 源数组的存储。 使用withMemoryRebound 将该指针“重新解释”为指向 到目标类型的元素。 使用Array(UnsafeBufferPointer(...) 创建一个数组 目标类型。

例子:

let source: [UInt16] = [1, 2, 3, 4]

let dest = source.withUnsafeBufferPointer 
    $0.baseAddress!.withMemoryRebound(to: UInt32.self, capacity: 2) 
        Array(UnsafeBufferPointer(start: $0, count: 2))
    


print(dest) // [131073, 262147]

或者作为一个通用函数:

func convertArray<S, T>(_ source: [S], to: T.Type) -> [T] 
    let count = source.count * MemoryLayout<S>.stride/MemoryLayout<T>.stride
    return source.withUnsafeBufferPointer 
        $0.baseAddress!.withMemoryRebound(to: T.self, capacity: count) 
            Array(UnsafeBufferPointer(start: $0, count: count))
        
    


例子:

let source: [UInt16] = [1, 2, 3, 4]
let dest = convertArray(source, to: UInt32.self)
print(dest) // [131073, 262147]

如果你只需要一个(临时的)视图对数组存储的解释 在另一种类型中,您可以避免 Array 创建 并使用UnsafeBufferPointer(这是Collection和 有类似数组的方法)而不复制数据:

source.withUnsafeBufferPointer 
    $0.baseAddress!.withMemoryRebound(to: UInt32.self, capacity: 2) 
        let u32bufptr = UnsafeBufferPointer(start: $0, count: 2)

        // ... Operate on u32bufptr ...
        for elem in u32bufptr  print(elem) 
    

【讨论】:

像魅力一样工作。请注意,这不会做大端。如果您是通过谷歌搜索有关大端的内容来到这里,请使用 UInt32 的 bigEndian 方法。

以上是关于将 [type_a] 转换为 [type_b]的主要内容,如果未能解决你的问题,请参考以下文章

pytorch张量torch.Tensor类型的构建与相互转换以及torch.type()和torch.type_as()的用法

pytorch张量torch.Tensor类型的构建与相互转换以及torch.type()和torch.type_as()的用法

pytorch张量torch.Tensor类型的构建与相互转换以及torch.type()和torch.type_as()的用法

pytorch张量torch.Tensor类型的构建与相互转换以及torch.type()和torch.type_as()的用法

将不同的文件加载到带有子文件夹的 SQL Server

如何在选择 oracle 中将值分组到单行