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

时间:2016-03-08 22:35:26

标签: swift swift-extensions swift-protocols

我认为我对Swift类型/协议/泛型的认知已经溢出。我一直在使用扩展“输入流字节”的模式,例如:

echo str_replace($search, "<span class='highlight'>$search</span>", $post['post_content']);

它过去曾用于简单的工作。今天我玩的是以下内容:

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

工作正常。但是,如果我尝试将两者放在一起,比如

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

然后我收到以下错误:

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

IndexingGenerator不符合GeneratorType吗?它的元素不是UInt8吗?使用IndexingGenerator时出错吗?我不能将参数类型指定为GeneratorType(虽然我真的希望能够)。

我还在等待Swift类型的灯泡闪烁。有时候我真的很喜欢这门语言。其他日子,我觉得我正在大吼我的狗试图让他来,而他只是盯着我而不动,然后转身追逐街道。

1 个答案:

答案 0 :(得分:2)

试试这个:

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

更新

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