Kotlin: ¿Qué hacen los operadores más / less unarios con los numbers?

Me he dado count en Kotlin que ya unaryMinus operadores definidos unaryPlus y unaryMinus en todos los types de numbers.

¿Cuál es el propósito de estos operadores? ¿Están de alguna manera conectados a las forms de prefijo de inc y dec ?

    Otros han definido el significado básico de unaryMinus y unaryPlus , y en realidad sobre los types numéricos, es posible que en realidad ni siquiera se los llame como funciones. Por ejemplo, la encoding +x o x.unaryPlus() genera el mismo bytecode (donde x es tipo Int ):

     ILOAD 1 ISTORE 2 

    Y el código -x o x.unaryMinus() genera el bytecode idéntico:

     ILOAD 1 INEG ISTORE 2 

    Pero hay más cosas que esto …

    Entonces, ¿por qué el comstackdor incluso genera algo para +x ? Algunas personas dirán que +x y x.unaryPlus() no hacen nada, y que -x y x.unaryMinus() solo invierten el signo. Eso no es correcto En Java es más complicado porque puede involucrar el ensanchamiento y el desempaquetado, consulte Promoción numérica unaria, que explica las consecuencias completas de estos operadores. Esto tiene consecuencias para los valores en caja y los types más pequeños que Int . Para el valor de tipo Short y Byte estos operadores devolverán un nuevo valor unboxed ampliado de tipo Int . Y como ambos operadores tienen esta funcionalidad más oculta, ambos deben generar bytecode incluso si no cree que +x hace nada. Por cierto, esto es similar a lo que hace el lenguaje C y se llama Conversiones aritméticas habituales .

    Por lo tanto, este código no es válido:

     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 

    En estos casos numéricos en los types numéricos básicos, son solo magia del comstackdor para permitir que la idea de estos operadores se equipare con las funciones del operador que es posible que desee sobrecargar en otras classs.

    Para otros usos, como sobrecarga de operador …

    Pero están ahí para algo más que solo el uso matemático y se pueden usar en cualquier class como operador. Kotlin expone a los operadores como funciones para que pueda aplicar la sobrecarga del operador en un set específico de operadores que incluyen unaryMinus y unaryPlus .

    Podría usarlos para definir operadores para mis classs o las existentes. Por ejemplo, tengo un Set<Things> donde Things es una class enum junto con un operador unaryMinus() para negar los contenidos del set finito de opciones:

     enum class Things { ONE, TWO, THREE, FOUR, FIVE } operator fun Set<Things>.unaryMinus() = Things.values().toSet().minus(this) 

    Y luego puedo negar mi enumeración siempre que quiera:

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

    Tenga en count que tuve que declarar mi function de extensión con el operator modificador o esto no funcionará. El comstackdor te recordará si olvidas esto cuando tratas de usar el operador:

    Error: (y, x) Kotlin: se requiere el modificador 'operator' en 'unaryMinus' en 'com.my.favorite.package.SomeClass'

    Estos operadores son los signos de los integers. Aquí hay unos ejemplos:

    +5 llama a 5.unaryPlus() y devuelve 5.

    -5 llama a 5.unaryMinus() y devuelve -5.

    -(-5) llama a 5.unaryMinus().unaryMinus() y devuelve 5.

    El propósito de esos operadores es poder escribir:

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

    No están directamente relacionados con los operadores ++ / inc y -- / dec , pero se pueden usar en set.

    Tenga en count que las siguientes expresiones son diferentes:

     --a // a = a.dec() -(-a) // a.unaryMinus().unaryMinus()