Home > Back-end >  How to cast the generic result of a generic Swift method?
How to cast the generic result of a generic Swift method?

Time:12-07

Assuming I have overloaded a Swift method like this

func someValue<T> ( _ name: PropertyName ) -> T? {
    // ...
}

func someValue ( _ name: PropertyName ) -> URL? {
    // ...
}

I can call this method like this

let u = o.someValue("propA")

And u will be of type URL?. Or I can also call it like this

let i: Int? = o.someValue("propB")
let s: String? = o.someValue("propC")

And i will be Int? and s will be String?.

But how can I use the result of this method call without assigning it to a variable? E.g. I want to use it for loop or maybe simpler, in a switch statement:

switch o.someValue("propB") {

This call will assume the result is URL?:

switch o.someValue("propB") as? Int {

I am told that URL? cannot be casted to Int, which is correct. But URL? means that already the wrong method is being called in the first place.

Update
Here is a minimal test case as I must not post the original code here.

https://swiftfiddle.com/srkys22vofdqlpl2sglnfs4q5u

CodePudding user response:

switch o.someValue("propB") as Int? {

and

switch o.someValue("propB") as URL? {

work fine. You are mistaken in saying

Doesn't work


You may also disambiguate like

(o.someValue as (_ name: PropertyName) -> Int?)("propB")
(o.someValue as (_ name: PropertyName) -> URL?)("propB")

…though you should not have to.

CodePudding user response:

switch o.someValue("propB") as? Int {

will not work as the compiler interprets that as

(switch o.someValue("propB")) as? Int {

in which case the URL? returning method wins, which is most specific overload, and then the case will fails as URL? cannot be cased to Int.

And then pointed out, that the correct code needs to be

switch o.someValue("propB") as Int? {

Note how the question mark is the only thing that moved here. As now the cast can match the generic version, too. This is basically hinted by the first line of Jessy's answer.

  • Related