Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this base type extension work?

Trying to play with extensions, but am having issues getting the following to work:

let value = -13
abs(value)

extension Int {
    var abs:Int {
        return abs(self) // -> Cannot invoke 'abs' with an argument list of type '(Int)'
    }
}

value.abs

The compile error is weird, because it demonstrably runs the abs() function directly above with an Int as an argument. I've still got some light bulbs to trigger for generics I guess. Enlighten me.

like image 710
Travis Griggs Avatar asked May 05 '15 22:05

Travis Griggs


People also ask

Why are my Chrome extensions not working?

Corrupted browser user profile – Another root cause that might be triggering this particular behavior in Google Chrome is a corrupted user profile. For several different reasons, your user profile might be unable to call upon Extension Manager, which will end up breaking all your available Chrome extensions.

How do I fix the extensions not loading?

Click on three vertical dots in the top-right corner and head over to More Tools > Extensions. Turn on the toggle for Developer mode. Click on Update to update all extensions. If extensions begin to load properly with this fix, try manually updating your extensions from time to time to avoid facing the same issue again. 3. Cached Data

Do extensions interfere with my browser's processing?

Using more than one extension serving the same purpose can cause interference in their processing. How likely it is for extensions to interfere depends on the nature and job of the extension. The higher the extension's involvement with your browser's processing, the higher the chances of having this issue.

How likely is it for extensions to interfere?

How likely it is for extensions to interfere depends on the nature and job of the extension. The higher the extension's involvement with your browser's processing, the higher the chances of having this issue. If the extension isn't working properly, check whether you have any similar extensions installed.


3 Answers

It appears just a call resolution problem. This will work:

let value = -13
abs(value)


extension Int {
    var abs1:Int {
        return abs(self)
    }
}

value.abs1

And this will work too:

extension Int {
    var abs:Int {
        return self < 0 ? -self : self
    }
}

value.abs
like image 39
Matteo Piombo Avatar answered Sep 22 '22 06:09

Matteo Piombo


The Swift compiler is confused that you use the abs variable as a function, which it cannot do. Now you could look at all the answers and rename your variable, but these do not give insight in how Swift functions work.

Swift automatically imports the Swift framework, where it defines its static functions. To use these functions, you usually do not need to specify that it's from the framework, but in cases like this, you should specify that you want to use the abs method from the Swift framework.

So after all the explanation, here's your code, which will work:

let value = -13
abs(value)

extension Int {
    var abs: Int {
        return Swift.abs(self)
    }
}

value.abs
like image 164
vrwim Avatar answered Sep 22 '22 06:09

vrwim


The problem here is that you are extending Int to add a variable named abs -- which is also the name of the function you are calling.

When you try to call the function abs() on the Int, it sees the variable abs that you created and it is confused because it thinks you are trying to return that variable and doesn't understand why you are sending it a parameter.

If you rename your variable to absoluteValue or anything else really, it should work.

let value = -13
abs(value)

extension Int {
var absoluteValue:Int {
        return abs(self)
    }
}

value.abs

Update: As others have stated, you can also solve the disambiguation of the use of abs by explicitly calling the function within the Swift framework. This should work just as well as the above solution.

let value = -13
abs(value)

extension Int {
var abs:Int {
        return Swift.abs(self)
    }
}

value.abs

Though, personally, I would still rename my new function to absoluteValue as in the first example so that its clear that you aren't calling the Swift.abs() when you use your abs variable.

like image 23
AnthonyMDev Avatar answered Sep 25 '22 06:09

AnthonyMDev