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.