【问题标题】:Using swift protocols with associated types generically一般使用带有关联类型的 swift 协议
【发布时间】:2016-06-23 05:03:30
【问题描述】:

我有一个关于 Swift 的类建模问题。我有一系列类,每个类都执行相同的任务(在下面的示例中,解码),但它们是专门的,并且每个生成不同类型的对象。

在某些情况下,我希望能够谈论我的解码器,例如 getGeneralInfo()getDecoderForIdentifier()。在其他情况下,例如我在进行解码操作时,我将直接实例化该类或使用as?

以下代码不起作用,因为当 Decoder 具有关联类型时,您不能将其用作返回类型。

我的解决方案是从协议中删除 decode() 并让每个类只实现自己的。然后我需要在需要的地方直接实例化具体类。这是可行的,但它让我很难过。

有什么办法可以让编译器强制执行“所有解码器都应该根据它们的关联类型有一个decode() 方法”?

我尝试过使用泛型超类,但它要求我为decode() 提供一个方法体,如果您的返回类型不是可选的,这将非常麻烦。

protocol Decoder {
    associatedtype Model
    func getGeneralInfo() -> GeneralInfo
    func decode(sourceData: Data) -> Model
}

// This return type is not allowed because Decoder has an associated type
func getDecoderForIdentifier(id: String) -> Decoder {
    if id == "mp3" {
        return Mp3Decoder()
    }
    if id == "wave" {
        return WaveDecoder()
    }
    /* ... */
}

class Mp3Decoder: Decoder {
    typealias Model = Mp3Info

    func getGeneralInfo() -> GeneralInfo {
        let info = GeneralInfo()
        /* ... */
        return info
    }

    func decode(sourceData: Data) -> Model {
        let result = Mp3Info()
        /* ... */
        return result
    }
}

class WaveDecoder: Decoder {
    typealias Model = WaveInfo

    /* ... similar to mp3 ... */
}

【问题讨论】:

    标签: swift generics swift-protocols


    【解决方案1】:

    如果您将Model 设为协议,那么您可以返回Decoder,因为它不需要关联类型。

    protocol Model { 
        // ...
    }
    
    protocol Decoder {
        func getGeneralInfo() -> GeneralInfo
        func decode(sourceData: Data) -> Model
    }
    
    class Mp3Decoder: Decoder {
    
        func getGeneralInfo() -> GeneralInfo {
            let info = GeneralInfo()
            // ...
            return info
        }
    
        func decode(sourceData: Data) -> Model {
            let result = Mp3Info()
            // ...
            return result
        }
    
    }
    
    func getDecoderForIdentifier(id: String) -> Decoder {
        if id == "mp3" {
            return Mp3Decoder()
        }
        // ...
    }
    

    【讨论】:

    • 啊,真聪明!我还没有说服自己这个结构是个好主意,但你肯定解决了我遇到的最大问题,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2019-08-05
    • 1970-01-01
    相关资源
    最近更新 更多