1

我想创建一个UnsafeMutablePointer仅影响UnsafeMutablePointer<UInt8>...的扩展程序

我知道这些说明是相关的,但我不确定如何:

扩展泛型类型时,您不提供类型参数列表作为扩展定义的一部分。相反,原始类型定义中的类型参数列表在扩展的主体中可用,并且原始类型参数名称用于引用原始定义中的类型参数。

基本上,我正在尝试使用这种方法:

func toSwift(length: Int) -> [Int] {
    var retVal : [Int] = []
    for i in 0..<length {
        retVal.append(Int(self[i]))
    }
    return retVal
}

self没有UnsafeMutablePointer<UInt8>作为参数的情况下采取行动......这可能吗?

4

2 回答 2

4

斯威夫特 3.1 更新

从 Swift 3.1(Xcode 8.3 beta 版提供)开始,现在支持具体的同类型要求。你现在可以说:

extension UnsafeMutablePointer where Pointee == UInt8 {
    func asArray(withLength length: Int) -> [Int] {
        return UnsafeBufferPointer(start: self, count: length).map(Int.init)
    }
}

斯威夫特前 3.1

可以这样做——尽管它不是特别好。您必须创建一个新协议才能“标记”该UInt8类型,然后将您的扩展限制到该协议。它也不允许您轻松指定Int(...)初始化程序可以接受_UInt8Type输入 - 您必须实现一个 hacky 'shadow' 方法来做到这一点。

protocol _UInt8Type {
    func _asInt() -> Int
}
extension UInt8 : _UInt8Type {
    func _asInt() -> Int {
        return Int(self)
    }
}

// Change 'Pointee' to 'Memory' for Swift 2
extension UnsafeMutablePointer where Pointee : _UInt8Type {
    func asArray(withLength length:Int) -> [Int] {
        return UnsafeBufferPointer(start: self, count: length).map{$0._asInt()}
    }
}

总而言之,我更愿意保持这个完全通用并使用@AMomchilov 的解决方案。我只是为了完成而添加这个。

尽管值得注意的是,作为 Swift Generics Manifesto 的一部分extension Type where Generic == SomeType已经提出了对扩展 ( )具有具体的相同类型要求- 所以希望这在未来的 Swift 版本中是可能的。

于 2016-06-22T21:15:16.513 回答
2

目前,您只能对协议执行此操作,而不是特定的类或结构。您可以制作一个虚拟协议并用它扩展您的类/结构,就像originaluser2 的 answer一样。

但是,我认为没有理由不保留此代码的通用性。你觉得这怎么样?

extension UnsafeMutablePointer {
    func toArray(withLength length: UInt) -> [Memory] { //Change "Memory" to "Pointee" in Swift 3
        return Array(UnsafeBufferPointer(start: self, count: Int(length)))
    }
}
于 2016-06-22T20:50:28.097 回答