如何将通用协议作为函数参数传递

How to pass generic protocol as function parameter

我必须将协议作为参数传递给函数。协议是通用的,具有关联类型。我找不到好的方法。

我想要实现的基本上是在 json 中存储一个键值对。 所以我有一个通用数据类型协议,它 sets/gets 值(根据数据类型设置和获取)

在另一个协议中,我想将这个通用数据类型协议作为函数参数传递。

protocol Datatype {
    associatedtype dataType
    
    func get(json: JSON) -> dataType?
    func set(json:inout JSON, key: String, value: dataType)
}

class DatatypeString: Datatype{
    
    typealias dataType = String

    func get(json: JSON) -> dataType? {
       return json.stringValue
    }

    func set(json: inout JSON, key: String, value: dataType) {
        json[key] = JSON(value)
    }
}

class DatatypeInt: Datatype{
    typealias dataType = Int
    
    func get(json: JSON) -> Int? {
        return json.intValue
    }
    
    func set(json: inout JSON, key: String, value: Int) {
        json[key] = JSON(value)
    }
}

在下面的代码中,我得到 Protocol 'Datatype' can only be used as a generic constraint because it has Self or associated type requirements

protocol Final {
    func set<T>(key: String, type: Datatype ,value: T) //getting error
}
class A : Final {
    var root:JSON = [:]
    
    func set<T>(key: String, type: Datatype, value: T) {
        type.set(json: &root, key: key, value: value)
    }
class test {
   let a = A()
   let dataType = DatatypeString()
   a.set("key",datatype, "VALUE")
}

您必须使用 Datatype 作为通用约束:

func set<T: Datatype>(key: String, type: T ,value: T.dataType)

请注意,您还需要将 value 参数的类型更改为 T.dataType,以实现类型安全。即你传入的值必须和type参数的dataType类型相同