简体   繁体   English

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

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

I've noticed in Kotlin that there are already defined unaryPlus and unaryMinus operators on all of the number types.我注意到在 Kotlin 中已经在所有数字类型上定义了unaryPlusunaryMinus运算符。

What's the purpose of these operators?这些运营商的目的是什么? Are they in some way connected to the prefix forms of inc and dec ?它们是否以某种方式连接到incdec的前缀形式?

Others have defined the basic meaning of unaryMinus and unaryPlus , and in reality on numeric types they may not actually even be called as functions. 其他人定义了unaryMinusunaryPlus的基本含义,实际上,在数字类型上,它们甚至可能甚至没有被称为函数。 For example, coding +x or x.unaryPlus() generates the same bytecode (where x is type Int ): 例如,编码+xx.unaryPlus()生成相同的字节码(其中xInt类型):

ILOAD 1
ISTORE 2

And the code -x or x.unaryMinus() generates the identical bytecode: 并且代码-xx.unaryMinus()生成相同的字节码:

ILOAD 1
INEG
ISTORE 2

But there is more going on that this... 但是还有更多的事情要做...

So why does the compiler even generate anything for +x ? 那么,为什么编译器甚至为+x生成任何东西? Some people will say that +x and x.unaryPlus() doesn't do anything, and that -x and x.unaryMinus() only reverses the sign. 有人会说+xx.unaryPlus()不会执行任何操作,而-xx.unaryMinus()只会反转符号。 That isn't correct. 那是不对的。 In Java it is more complicated because it can involve widening and unboxing, see Unary Numeric Promotion which explains the full consequences of these operators. 在Java中,它更为复杂,因为它可能涉及到扩展和装箱操作,请参阅一元数值升级 ,其中解释了这些运算符的全部结果。 This has consequences for boxed values and types smaller than Int . 这将导致装箱的值和类型小于Int For value of type Short and Byte these operators will return a new unboxed value widened of type Int . 对于ShortByte类型的值,这些运算符将返回一个新的未装箱值,其值将扩展为Int类型。 And since both operators have this more hidden functionality then both must generate bytecode even if you don't think +x does anything. 而且由于这两个运算符都具有这种更隐藏的功能,因此即使您认为+x都不做任何事情,它们都必须生成字节码。 By the way, this is similar to what C language does and it is called Usual Arithmetic Conversions . 顺便说一下,这类似于C语言所做的,被称为“ 常规算术转换”

Therefore this code is invalid: 因此,此代码无效:

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

In these numeric cases on the base numeric types they are just compiler magic to allow for the idea of these operators to be equated to operator functions that you might want to overload in other classes. 在这些基于基本数字类型的数字情况下,它们只是编译器的魔力,可以将这些运算符的概念等同于您可能希望在其他类中重载的运算符功能。

For other uses such as Operator Overloading... 对于其他用途,例如操作员超载...

But they are there for more than just mathematical use and can be used on any class as an operator. 但是它们不仅仅用于数学用途,而且可以作为运算符在任何类上使用。 Kotlin exposes operators as functions so that you can apply operator overloading on a specific set of operators which include unaryMinus and unaryPlus . Kotlin将运算符公开为函数,以便您可以将运算符重载应用于包括unaryMinusunaryPlus一组特定运算符。

I could use these to define operators for my own or existing classes. 我可以使用它们为自己或现有的类定义运算符。 For example I have a Set<Things> where Things is an enum class along with an unaryMinus() operator to negate the contents of the finite set of options: 例如,我有一个Set<Things> ,其中Things是一个枚举类,以及一个unaryMinus()运算符,用于取反有限选项集的内容:

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

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

And then I can negate my enum set whenever I want: 然后我可以随时取消我的枚举集:

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

Notice that I had to declare my extension function with the modifier operator or this will not work. 请注意,我必须使用修饰符operator声明扩展功能,否则将无法正常工作。 The compiler will remind you if you forget this when you try to use the operator: 尝试使用运算符时,如果忘记了此内容,编译器会提醒您:

Error:(y, x) Kotlin: 'operator' modifier is required on 'unaryMinus' in 'com.my.favorite.package.SomeClass' 错误:(y,x)Kotlin:“ com.my.favorite.package.SomeClass”中的“ unaryMinus”上需要“ operator”修饰符

These operators are the signs of the integers. 这些运算符是整数的符号。 Here are some examples: 这里有些例子:

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

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

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

The purpose of those operators is to be able to write: 这些运算符的目的是能够编写:

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

They are not directly related to ++ / inc and -- / dec operators however they can be used in conjunction. 它们与++ / inc-- / dec运算符没有直接关系,但是可以结合使用。

Notice that the following expressions are different: 请注意,以下表达式是不同的:

--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