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

时间:2016-06-04 13:12:06

标签: kotlin

是否可以定义一个可以像这样接口的通用取幂运算符:

> 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 {
...
}

但他们不允许像^

这样的符号

3 个答案:

答案 0 :(得分:19)

不幸的是,您无法定义新的运算符,只有predefined set个可以重载的运算符。稍后可能会将某些运算符添加到此集合中,Kotlin问题跟踪器中会有open issue

但是,您可以使用反引号名称来定义看起来像运算符的send扩展函数(尽管不那么漂亮):

infix

用法:

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

请注意,5 `^` 3 函数的优先级低于运算符的优先级,因此

infix

答案 1 :(得分:0)

没有。 Kotlin仅允许重载预定义的运算符集,如the documentation中所示。并且^不是其中之一(它甚至不是运算符AFAIK,因此它不能超载)。

答案 2 :(得分:0)

我与 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)

我对第一选项投票!