Swift中的动态协议一致性

Swift中的动态协议一致性,swift,swift3,Swift,Swift3,您好,我正在努力用swift语言解决动态协议一致性问题。请看代码 协议: protocol Object { init(by object: [String: Any]) } 具有协议对象一致性的自定义结构: struct Tree: Object { let treeName: String init(by object: [String: Any]) { self.treeName = object["tree"] as? String ??

您好,我正在努力用swift语言解决动态协议一致性问题。请看代码

协议:

protocol Object {

    init(by object: [String: Any])
}
具有协议对象一致性的自定义结构:

struct Tree: Object {

    let treeName: String

    init(by object: [String: Any]) {

        self.treeName = object["tree"] as? String ?? "Notree"
    }
}

struct Plant: Object {

    let plantName: String

    init(by object: [String : Any]) {

        self.plantName = object["tree"] as? String ?? ""
    }
}
上面的代码很好,直到对象成为
[String:Any]
。我不能像下面那样使用[[String:Any]]

let coconut = ["tree":"Coconut"] // => This fine
let allTrees = [["tree":"Apple"],["tree":"Orange"],["tree":"Jakfruit"]] //=> Here is the problem

 let aTree = Tree(by: coconut)
 let bTree = Tree(by: ["data":allTrees])
 let cTree = Plant(by: ["data":allTrees])
我不能使用对象数组。所以,我习惯于将对象存储在键“data”中。现在我使用了
extension:Array
confirm协议对象

extension Array: Object where Element == Object{

    init(by object: [String : Any]) {

        if let data = object["data"] as? [[String: Any]]{

            self  = data.map({ (object) -> Object in

//                return Plant.init(by: object) // => Works, But I need dynamic confirmance
//                return Tree.init(by: object) // => Works, But I need dynamic confirmance

                return Object.init(by: object) //=> How can I do?
            })
        }else{

            self = []
        }
    }
}
返回的
对象
显示错误无法实例化协议类型“对象”。我试图解决很多问题,但没能解决


有人能为这个问题提出更好的想法或解决方案吗?提前感谢您…

首先,您不应该使用约束
==Object
。你想说不仅
[Object]
对象
,而且
[Plant]
[Tree]
也是
对象
,对吗?为此,应该使用
:Object
约束。其次,可以使用
Element.init
初始化数组的新
元素。由于约束
元素:Object
,我们知道存在
init(by:)
初始化器:

extension Array: Object where Element: Object{

    init(by object: [String : Any]) {

        if let data = object["data"] as? [[String: Any]]{

            self  = data.map({ (object) in

                return Element.init(by: object)
            })
        }else{

            self = []
        }
    }
}
用法:

let trees = [Tree](by: ["data": allTrees])
下面是我认为更快捷的代码版本,使用-initialiser,在初始化对象失败时返回
nil

protocol Object {

    init?(by object: [String: Any])
}


struct Tree: Object {

    let treeName: String

    init?(by object: [String: Any]) {

        if let treeName = object["tree"] as? String {
            self.treeName = treeName
        } else {
            return nil
        }
    }
}

struct Plant: Object {

    let plantName: String

    init?(by object: [String : Any]) {

        if let plantName = object["tree"] as? String {
            self.plantName = plantName
        } else {
            return nil
        }
    }
}

extension Array: Object where Element: Object{

    init?(by object: [String : Any]) {

        if let data = object["data"] as? [[String: Any]]{
            self  = data.compactMap(Element.init)
        }else{
            return nil
        }
    }
}

非常感谢你!我花了几个小时才找到这个。