nacho4d nacho4d - 1 month ago 11
Swift Question

Calling a generic function in swift

I have the following struct, variable and a function:

struct MyModel {
var keyString: String
var keyNum: Int
}

let data = "{\"keyString\": \"valueString\", \"keyNum\": 1 }"

func myFunction<T: AnyObject>(str: String) throws -> T? {
return nil
}


How can I call the function with MyModel? Below code makes the compiler complain: "Generic parameter 'T' could not be inferred"

let myModel = try? myFunction(str: data) as? MyModel


Link to Swift REPL: http://swiftlang.ng.bluemix.net/#/repl/57f1fa479ce3c95fc38e63b3

Answer:



Thanks to @Sweeper this is what I came out with
(Swift Sandbox Code):

protocol Initializable {
init()
}

struct MyModel : Initializable {
var keyString: String = "ten"
var keyNum: Int = 10
public init() {
}
}

func stringToModel<T: Initializable>(str: String) throws -> T? {
return T() // TODO
}

func main() {
let maybeModel = (try? stringToModel(str: "whatever") as MyModel?) ?? nil
guard let model = maybeModel else {
print("ERROR")
return
}
print("keyNum \(model.keyNum) should be 10")
}

main()

Answer

Since your generic type parameter is declared with a constraint, like this:

func myFunction<T: AnyObject>

So whatever type you use, it must be a reference type or implement NSObjectProtocol or something like that.

A swift struct is a value type, so MyModel can't possibly be used as a generic type parameter.

Solutions:

  • Change the generic type constraint to <T: Any> to make it accept value types.

  • Remove the generic type constraint.

  • Change the struct to a class and add an initializer.
Comments