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