Extension for Generic Type `UnsafeMutablePointer<UInt8>`

杀马特。学长 韩版系。学妹 提交于 2019-11-29 12:44:18
Hamish

Swift 3.1 Update

As of Swift 3.1 (available with Xcode 8.3 beta), concrete same-type requirements are now supported. You can now just say:

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

Pre Swift 3.1

You can do this – although it's not particularly nice. You'll have to create a new protocol in order to 'tag' the UInt8 type, and then constrain your extension to that protocol. It also doesn't allow you to easily specify that the Int(...) initialiser can take a _UInt8Type input – you have to implement a hacky 'shadow' method to do that.

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()}
    }
}

All in all I'd prefer to keep this fully generic and go with @AMomchilov's solution. I'm only really adding this for the sake of completion.

Although it's worth noting that having concrete same-type requirements for extensions (extension Type where Generic == SomeType) has been proposed as a part of the Swift Generics Manifesto – so hopefully this will be possible in a future version of Swift.

Alexander

Currently, you can only do this for protocols, not particular classes or structs. You can make a dummy protocol and extend your class/struct with it, as with originaluser2's answer.

However, I don't see a reason not to keep this code generic. What do you think of this?

extension UnsafeMutablePointer {
    func toArray(withLength length: UInt) -> [Memory] { //Change "Memory" to "Pointee" in Swift 3
        return Array(UnsafeBufferPointer(start: self, count: Int(length)))
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!