Why is this base type extension not working?

Trying to play with extensions, but I have problems with 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 compilation error is strange, because it explicitly runs the abs() function immediately above with Int as an argument. I think I still have light bulbs for starting generics. Enlighten me.

+5
source share
4 answers

The Swift compiler is confused that you are using the abs variable as a function that it cannot do. Now you can look at all the answers and rename the variable, but they do not give an understanding of how the Swift functions work.

Swift automatically imports the Swift structure, where it defines its static functions. To use these functions, you usually do not need to indicate that it is from the framework, but in such cases you should indicate that you want to use the abs method from the Swift framework.

So, after all the explanation, here is your code that will work:

 let value = -13 abs(value) extension Int { var abs: Int { return Swift.abs(self) } } value.abs 
+4
source

This is 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 
+2
source

The problem is that you are expanding Int to add a variable called abs , which is also the name of the function being called.

When you try to call the abs() function on Int , it sees the created abs variable, and it gets confused because it thinks you are trying to return this variable and don’t understand why you are sending the parameter to it.

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

 let value = -13 abs(value) extension Int { var absoluteValue:Int { return abs(self) } } value.abs 

Update:. As others have argued, you can also resolve the issue of the uniqueness of using abs by explicitly calling a function within Swift . This should work as well as the above solution.

 let value = -13 abs(value) extension Int { var abs:Int { return Swift.abs(self) } } value.abs 

Although I would personally rename my new function to absoluteValue , as in the first example, so that it is clear that you are not calling Swift.abs() when using your abs variable.

+2
source

Due to the direction of the original two answers (the collision between the global free function and the var parameter that I defined), they need to be eliminated. Instead of running my own built-in implementation of abs or having to use a different name, I can use it correctly inside abs() using the Swift namespace.

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

It gives me the best of both worlds (IMO).

0
source

All Articles