如何在 Kotlin 中定义新的运算符?

17

是否可能定义一个通用的指数运算符,可以像这样进行接口化:

> 10^3         // 1000
> 2.71^2       // 7.3441
> 3.14^(-3.14) // 0.027..

根据文档,可以使用中缀函数扩展类:

// Define extension to Int
infix fun Int.exp(exponent: Int): Int {
...
}

但是它们不允许像^这样的符号。


1
顺便说一句,即使可能定义一个指数运算符,我也建议不要使用 ^。在Java、C#和许多其他语言中,^ 运算符执行 异或 操作,所以在Kotlin中看到它执行不同的操作会令人惊讶。 - ean5533
是的,** 可能是更安全的选择。 - TomTom
3个回答

33

很不幸,您无法定义新的运算符,只有一组预定义的可被重载的运算符。一些运算符可能会在以后添加到这个集合中,Kotlin问题跟踪器中有一个开放问题

但是,您可以使用反引号名称来定义infix扩展函数,这些函数看起来像运算符(尽管不太好看):

infix fun Int.`^`(exponent: Int): Int = ... 

使用方法:

5 `^` 3

请注意,infix函数的优先级低于运算符,因此

1 + 1 `^` 3 == 8

7
以上所有内容,但是“幸运的是” - voddan
1
我希望他们考虑添加一个幂运算符,因为它在任何类型的数学中都被广泛使用。在我看来,Math.pow 有点笨重。 - TomTom
@TomTom,你可以使用2.0.pow(4)。Pow是来自kotlin.math的函数。 - Ayxan Haqverdili

5

我使用 Math。在 Android Studio 中,不允许使用带引号的 ^ 符号。因此,我定义了一个反向的 ^ 运算符作为 v,虽然它看起来有点不美观,但比进行大量类型转换和使用 pow 表示法要好得多。

inline infix fun Double.v(exponent: Int): Double = this.pow(exponent)
inline infix fun Double.v(exponent: Long): Double = this.pow(exponent.toDouble())
inline infix fun Double.v(exponent: Double): Double = this.pow(exponent)
inline infix fun Int.v(exponent: Int): Double = this.toDouble().pow(exponent)
inline infix fun Int.v(exponent: Long): 
      Double = this.toDouble().pow(exponent.toDouble())
inline infix fun Int.v(exponent: Double): Double = this.toDouble().pow(exponent)
inline infix fun Long.v(exponent: Int): Double = this.toDouble().pow(exponent)
inline infix fun Long.v(exponent: Long): 
      Double = this.toDouble().pow(exponent.toDouble())
inline infix fun Long.v(exponent: Double): 
      Double = this.toDouble().pow(exponent)

inline使用在运行时不会增加额外的负载,即使在更重的循环内部也是如此。

不幸的是,损坏的运算符优先级强制你用括号将指数运算括起来。并且编译器强制你两侧添加空格。

毕竟,哪种方式看起来最好?

这样做呢?

var k=2  
...
println((k v 5)+3)

还是这个?
var k=2
 ... 
println(k.toDouble().pow(5) + 3)

我选择第一个选项!

3
太好了!那这个呢?inline infix fun <T : Number> T.v(exponent: T): Double = this.toDouble().pow(exponent.toDouble()) - yane
是的!你说得对。好主意。我会在我的代码中进行更改。 - Paulo Buchsbaum

0

不行。Kotlin 只允许重载一组预定义的运算符,如文档所示。而^不在其中(据我所知,它甚至不是一个运算符,因此无法被重载)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接