Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

swift - Extension for Generic Type `UnsafeMutablePointer<UInt8>`

I'd like to create an extension for UnsafeMutablePointer that only affects UnsafeMutablePointer<UInt8>...

I understand that these instructions are pertinent, but I'm not sure how:

When you extend a generic type, you do not provide a type parameter list as part of the extension’s definition. Instead, the type parameter list from the original type definition is available within the body of the extension, and the original type parameter names are used to refer to the type parameters from the original definition.

Basically, I'm trying to use this method:

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

to act on self without the UnsafeMutablePointer<UInt8> as a parameter... is this possible?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...