如何在Swift

时间:2019-04-01 08:57:34

标签: swift generics

我尝试实现一些不同的对象可以接收其唯一配置的逻辑。

我有很多类型不同的对象,它们可以请求自己的配置对象。

//Provider
protocol ConfigProvider {
    func config<R: ConfigReciever>(for reciever: R) -> R.ConfigType
}

class Factory {

}

extension Factory: ConfigProvider {
    func config<R: ConfigReciever>(for reciever: R) -> R.ConfigType {
        //How switch?
        return Config1(info: "hey") as! R.ConfigType
    }
}

//Reciever
protocol ConfigReciever: class {
    associatedtype ConfigType
    var dataSource: ConfigProvider? { get set }
}

struct Config1 {
    let info: String
}

class Object1: ConfigReciever {
    typealias ConfigType = Config1
    var dataSource: ConfigProvider?

    func execute() {
        let config = dataSource?.config(for: self)
        print("\(config!.info)")
    }
}

但是正确的实现Provider逻辑存在一些问题。 我不知道开关接收器如何创建正确的配置类型。 这有什么选择吗?

我知道,我可以在没有泛型的情况下(例如,使用configTypes枚举)实现此目的,但是我不想进行不必要的强制转换。

1 个答案:

答案 0 :(得分:0)

我建议使用中间协议

// Wrapper container
protocol Container { }

extension String: Container { }
extension Int: Container { }

// Implementation

    //Provider
    protocol ConfigProvider {
        func config<R>(for reciever: R) -> Configuration where R : ConfigReciever, R.ConfigType: Configuration
    }

    class Factory { }

    extension Factory: ConfigProvider {
        func config<R>(for reciever: R) -> Configuration where R : ConfigReciever, R.ConfigType: Configuration {
            return Config1(info: "hey")
        }
    }

    //Reciever
    protocol ConfigReciever: class {
        associatedtype ConfigType
        var dataSource: ConfigProvider? { get set }
    }

    protocol Configuration {
        var info: Container { get set }
    }

    struct Config1: Configuration {
        var info: String
    }

    class Object1: ConfigReciever {
        typealias ConfigType = Config1
        var dataSource: ConfigProvider?

        func execute() {
            let config = dataSource?.config(for: self)
// here you should case into wanted structure:
if let stringInfo = config?.info as? String {
            print("\(stringInfo)")
    }
        }
    }

    let factory = Factory()
    let obj = Object1()

    obj.dataSource = factory

    obj.execute()
相关问题