PDD
PDD

Reputation: 13

How to pass generic protocol as function parameter

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

Answers (1)

Sweeper
Sweeper

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

Related Questions