繁体   English   中英

Kotlin:一元加/减运算符对数字有什么作用?

[英]Kotlin: What do the unary plus/minus operators do on numbers?

我注意到在 Kotlin 中已经在所有数字类型上定义了unaryPlusunaryMinus运算符。

这些运营商的目的是什么? 它们是否以某种方式连接到incdec的前缀形式?

其他人定义了unaryMinusunaryPlus的基本含义,实际上,在数字类型上,它们甚至可能甚至没有被称为函数。 例如,编码+xx.unaryPlus()生成相同的字节码(其中xInt类型):

ILOAD 1
ISTORE 2

并且代码-xx.unaryMinus()生成相同的字节码:

ILOAD 1
INEG
ISTORE 2

但是还有更多的事情要做...

那么,为什么编译器甚至为+x生成任何东西? 有人会说+xx.unaryPlus()不会执行任何操作,而-xx.unaryMinus()只会反转符号。 那是不对的。 在Java中,它更为复杂,因为它可能涉及到扩展和装箱操作,请参阅一元数值升级 ,其中解释了这些运算符的全部结果。 这将导致装箱的值和类型小于Int 对于ShortByte类型的值,这些运算符将返回一个新的未装箱值,其值将扩展为Int类型。 而且由于这两个运算符都具有这种更隐藏的功能,因此即使您认为+x都不做任何事情,它们都必须生成字节码。 顺便说一下,这类似于C语言所做的,被称为“ 常规算术转换”

因此,此代码无效:

val x: Short = 1
val y1: Short = +x              // incompatible types
val y2: Short = x.unaryPlus()   // incompatible types
val z1: Short = -x              // incompatible types
val z2: Short = x.unaryMinus()  // incompatible types

在这些基于基本数字类型的数字情况下,它们只是编译器的魔力,可以将这些运算符的概念等同于您可能希望在其他类中重载的运算符功能。

对于其他用途,例如操作员超载...

但是它们不仅仅用于数学用途,而且可以作为运算符在任何类上使用。 Kotlin将运算符公开为函数,以便您可以将运算符重载应用于包括unaryMinusunaryPlus一组特定运算符。

我可以使用它们为自己或现有的类定义运算符。 例如,我有一个Set<Things> ,其中Things是一个枚举类,以及一个unaryMinus()运算符,用于取反有限选项集的内容:

enum class Things {
    ONE, TWO, THREE, FOUR, FIVE
}

operator fun Set<Things>.unaryMinus() = Things.values().toSet().minus(this)

然后我可以随时取消我的枚举集:

val current = setOf(Things.THREE, Things.FIVE)
println(-current)       // [ONE, TWO, FOUR]
println(-(-current))    // [THREE, FIVE]

请注意,我必须使用修饰符operator声明扩展功能,否则将无法正常工作。 尝试使用运算符时,如果忘记了此内容,编译器会提醒您:

错误:(y,x)Kotlin:“ com.my.favorite.package.SomeClass”中的“ unaryMinus”上需要“ operator”修饰符

这些运算符是整数的符号。 这里有些例子:

+5调用5.unaryPlus()并返回5。

-5调用5.unaryMinus()并返回-5。

-(-5)调用5.unaryMinus().unaryMinus()并返回5。

这些运算符的目的是能够编写:

val a = System.nanoTime()
val b = -a // a.unaryMinus()
val c = +b // b.unaryPlus()

它们与++ / inc-- / dec运算符没有直接关系,但是可以结合使用。

请注意,以下表达式是不同的:

--a // a = a.dec()
-(-a) // a.unaryMinus().unaryMinus()
fun main(){
var a = 34
var b = 56


println("Orignal value:"+ a)
println("Orignal value:"+ b

//The value will not change using .unaryPlus() will generate bytecode
println("After unary plus:" + a.unaryPlus())
//The value will invert the sign using .unaryMinus() will generate bytecode
println("After unary minus:" + b.unaryMinus())

}

Solution:
Orignal value:34
Orignal value:56
After unary plus:35
After unary minus:-55

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM