简体   繁体   English

Swift 为什么我的生成器协议扩展不起作用?

[英]Swift why doesn't my generator protocol extension work?

I think my cognition for Swift types/protocols/generics has overflowed.我觉得我对 Swift 类型/协议/泛型的认知已经溢出了。 I've been using the pattern of extending "an input stream bytes" by doing something like:我一直在通过执行以下操作来使用扩展“输入流字节”的模式:

extension GeneratorType where Element == UInt8 {
    func foobar()  {
        ...
    }
}

It's worked in the past for simple stuff.它过去适用于简单的东西。 And today I was playing with the following:今天我正在玩以下游戏:

protocol Unpackable {
    static func unpack(inout input:IndexingGenerator<[UInt8]>) -> Self
}

extension UInt8:Unpackable {
    static func unpack(inout input:IndexingGenerator<[UInt8]>) -> UInt8 {
        return input.next()!
    }
}

extension UInt16:Unpackable {
    static func unpack(inout input:IndexingGenerator<[UInt8]>) -> UInt16 {
        return UInt16(input.next()!) | (UInt16(input.next()!) << 8)
    }
}

Works fine.工作正常。 But if I try to put the two together with something like但是,如果我尝试将两者放在一起

extension GeneratorType where Element == UInt8 {
    func unpackAll() -> (UInt8, UInt16) {
        return (UInt8.unpack(&self), UInt16.unpack(&self))
}

then I get the following error:然后我收到以下错误:

Cannot convert value of type 'Self' to expected argument type 'IndexingGenerator<[UInt8]>'

Doesn't an IndexingGenerator conform to GeneratorType? IndexingGenerator 不符合 GeneratorType 吗? Is its Element not UInt8?它的元素不是 UInt8 吗? Is the error in using IndexingGenerator?是使用 IndexingGenerator 的错误吗? I can't specify the argument types as GeneratorType (though I'd really like to be able to).我无法将参数类型指定为 GeneratorType(尽管我真的很想这样做)。

I'm still waiting for the light bulb to flicker on for Swift types.我仍在等待灯泡为 Swift 类型闪烁。 Some days I really like the language.有些日子我真的很喜欢这门语言。 Other days, I feel like I'm yelling at my dog trying to get him to come, and he just stares at me without moving, then turns and chases down the street anyway.其他时候,我觉得我在对我的狗大喊大叫,试图让他过来,他只是盯着我一动不动,然后转身追到街上。

Try this:尝试这个:

extension GeneratorType where Element == UInt8 {
    func unpackAll() -> (UInt8, UInt16)? {
        guard let _self = self as? IndexingGenerator<[Element]> else { return nil }
        var vSelf = _self
        return (UInt8.unpack(&vSelf), UInt16.unpack(&vSelf))
    }
}

Update:更新:

protocol Unpackable {
    static func unpack<T : GeneratorType where T.Element == UInt8>(inout input:T) -> Self
}

extension UInt8: Unpackable {
    static func unpack<T : GeneratorType where T.Element == UInt8>(inout input: T) -> UInt8 {
        return input.next()!
    }
}

extension UInt16: Unpackable {
    static func unpack<T : GeneratorType where T.Element == UInt8>(inout input: T) -> UInt16 {
        return UInt16(input.next()!) | (UInt16(input.next()!) << 8)
    }
}

extension GeneratorType where Element == UInt8 {
    mutating func unpackAll() -> (UInt8, UInt16) {
        return (UInt8.unpack(&self), UInt16.unpack(&self))
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM