Reputation: 13
I have to pass a protocol as a parameter to a function. Protocol is generic, has associated type. I couldn't find a good way to do that.
What I want to achieve basically storing a key-value pair in json. So I have one Generic Datatype protocol which sets/gets value (sets and gets according to datatype)
In another protocol I want to pass this generic Datatype protocol as a function parameter.
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)
}
}
In the below code I'm getting 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")
}
Upvotes: 0
Views: 567
Reputation: 274835
You must use Datatype
as a generic constraint:
func set<T: Datatype>(key: String, type: T ,value: T.dataType)
Note how you also need to change the type of the value
parameter to T.dataType
, for this to be type safe. That is, the value you pass in must be the same type as the dataType
of the type
parameter.
Upvotes: 1