2016-06-23 43 views
1

我有Swift的类建模问题。我有一系列的每个类都执行相同的任务(在我的示例中,Decoding),但它们是专用的,每个都产生不同类型的对象。一般使用相关类型的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 ... */ 
} 

回答

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() 
    } 
    // ... 
} 
+0

啊,这很聪明!我还没有说服自己,这个结构是一个好主意,但你肯定已经解决了我遇到的最大问题,谢谢。 – Tom

相关问题