提问者:小点点

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


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

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

在另一个协议中,我希望将这个泛型数据类型协议作为函数参数传递。

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)
    }
}

在下面的代码中,我得到的协议“dataType”只能用作泛型约束,因为它有自身或关联的类型要求

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")
}

共1个答案

匿名用户

必须使用dataType作为泛型约束:

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

请注意,您还需要将value参数的类型更改为t.dataType,以确保类型安全。也就是说,您传入的值必须是与type参数的dataType相同的类型。