为什么这个基类型扩展不起作用?

时间:2022-08-23 14:53:10

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.

编译错误很奇怪,因为它可以使用Int作为参数直接在上面运行abs()函数。我猜我还有一些灯泡可以触发仿制药。开导我。

4 个解决方案

#1


4  

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编译器很混淆你使用abs变量作为函数,它无法做到。现在,您可以查看所有答案并重命名变量,但这些并不能让您深入了解Swift函数的工作原理。

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.

Swift自动导入Swift框架,在框架中定义静态函数。要使用这些函数,通常不需要指定它来自框架,但在这种情况下,您应该指定要使用Swift框架中的abs方法。

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

#2


2  

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

#3


2  

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.

这里的问题是你扩展Int以添加一个名为abs的变量 - 这也是你正在调用的函数的名称。

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.

当你尝试在Int上调用函数abs()时,它会看到你创建的变量abs并且它被混淆,因为它认为你试图返回该变量并且不理解你为什么要向它发送参数。

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

如果你将变量重命名为absoluteValue或其他任何东西,它应该可以工作。

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.

更新:正如其他人所说,你也可以通过在Swift框架中显式调用函数来解决使用abs的歧义。这应该与上述解决方案一样有效。

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.

虽然,就个人而言,我仍然会像第一个例子那样将我的新函数重命名为absoluteValue,以便在使用abs变量时清楚地表明你没有调用Swift.abs()。

#4


0  

Thanks to the direction of the original two answers (* between global free function and the var I was defining), they have to be disambiguated. Rather than do my own inline implementation of abs or be forced to use a different name, I can properly scope the inside abs() using the Swift namespace.

由于原始两个答案的方向(全局*函数和我定义的var之间的冲突),它们必须消除歧义。我可以使用Swift命名空间正确地限定内部abs(),而不是使用我自己的abs内联实现或强制使用不同的名称。

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

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

这给了我两全其美(IMO)。

#1


4  

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编译器很混淆你使用abs变量作为函数,它无法做到。现在,您可以查看所有答案并重命名变量,但这些并不能让您深入了解Swift函数的工作原理。

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.

Swift自动导入Swift框架,在框架中定义静态函数。要使用这些函数,通常不需要指定它来自框架,但在这种情况下,您应该指定要使用Swift框架中的abs方法。

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

#2


2  

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

#3


2  

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.

这里的问题是你扩展Int以添加一个名为abs的变量 - 这也是你正在调用的函数的名称。

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.

当你尝试在Int上调用函数abs()时,它会看到你创建的变量abs并且它被混淆,因为它认为你试图返回该变量并且不理解你为什么要向它发送参数。

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

如果你将变量重命名为absoluteValue或其他任何东西,它应该可以工作。

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.

更新:正如其他人所说,你也可以通过在Swift框架中显式调用函数来解决使用abs的歧义。这应该与上述解决方案一样有效。

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.

虽然,就个人而言,我仍然会像第一个例子那样将我的新函数重命名为absoluteValue,以便在使用abs变量时清楚地表明你没有调用Swift.abs()。

#4


0  

Thanks to the direction of the original two answers (* between global free function and the var I was defining), they have to be disambiguated. Rather than do my own inline implementation of abs or be forced to use a different name, I can properly scope the inside abs() using the Swift namespace.

由于原始两个答案的方向(全局*函数和我定义的var之间的冲突),它们必须消除歧义。我可以使用Swift命名空间正确地限定内部abs(),而不是使用我自己的abs内联实现或强制使用不同的名称。

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

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

这给了我两全其美(IMO)。