Reputation: 9431
I'm trying to write generic handler
function which will receive ResourceModel
instances and process them somehow:
func handleGeneric<R, M: ResourceModel>(resource: R, modelType: M.Type) {
I got stuck with Swift protocols usage though
This is the error I get:
Resource.playground:60:20: note: generic parameter 'R' of global function 'handleGeneric(resource:modelType:)' declared here
func handleGeneric<R, M: ResourceModel>(resource: R, modelType: M.Type) {
import UIKit
// Structs
struct ResourceA: Decodable {
let id: Int
let name: String
}
struct ResourceB: Decodable {
let id: Int
let number: Int
}
// Models
protocol ResourceModel {
associatedtype R
init(resource: R)
}
class ModelA: ResourceModel {
var id: Int = 0
var name: String = ""
convenience required init(resource: ResourceA) {
self.init()
id = resource.id
name = resource.name
}
}
class ModelB: ResourceModel {
var id: Int = 0
var number: Int = 0
convenience required init(resource: ResourceB) {
self.init()
id = resource.id
number = resource.number
}
}
// Save
func handleA(resource: ResourceA) {
let m = ModelA(resource: resource)
// save ... A ...
print("handle A completed")
}
func handleB(resource: ResourceB) {
let m = ModelB(resource: resource)
// ... save B ...
print("handle B completed")
}
// Generic handler
func handleGeneric<R, M: ResourceModel>(resource: R, modelType: M.Type) {
let m = M.init(resource: resource)
// ... save m ...
print("handle generic completed")
}
// Download
func downloadA() {
let r = ResourceA(id: 1, name: "A")
handleA(resource: r)
}
func downloadB() {
let r = ResourceB(id: 2, number: 10)
handleB(resource: r)
}
downloadA()
downloadB()
The question is how can I implement the generic function I need? I.e.
handleGeneric<ResourceA, ModelA>(ResourceA(id: 1, name: "A"))
handleGeneric<ResourceB, ModelB>(ResourceB(id: 2, number: 10))
handleGeneric<ResourceC, ModelC>(ResourceC(id: 3, "foo": "bar"))
handleGeneric<ResourceD, ModelD>(ResourceD(id: 4, "egg": "spam"))
Upd
I tried
handleGeneric(resource: ResourceA(id: 1, name: "A"), modelType: ModelA.Type)
handleGeneric(resource: ResourceB(id: 2, number: 10), modelType: ModelB.Type)
But I get
Cannot convert value of type 'ResourceA' to expected argument type '_.R'
Upvotes: 1
Views: 82
Reputation: 89172
Don't put R
in the <>
-- use M.R
in your signature.
func handleGeneric<M: ResourceModel>(resource: M.R, modelType: M.Type) {
Upvotes: 1