Descargar

3. Operadores

Aritméticos

var a = 7
var b = 2
print(a + b, a - b, a * b, a / b, a % b, a ** b)  // 9 5 14 3.5 1 49
print(-a, -7 % 3)                                 // el módulo tiene el signo del divisor: 2
▶ Probar en el editor

+ también une textos ("a" + "b"), listas ([1] + [2]) y, si un lado es texto, convierte el otro: "Puntos: " + 10. * repite textos: "ab" * 3.

Asignación

var x = 10
x += 5; x -= 2; x *= 3; x /= 3; x %= 7
x++
x--
var nombre = null
nombre ??= "anónimo" // asigna solo si es null
print(x, nombre)
▶ Probar en el editor

**= eleva y guarda: p **= 2 es p = p ** 2.

Comparación

==, !=, <, <=, >, >=. Los textos se comparan en orden alfabético; las listas y mapas, por contenido; los struct, por sus campos; los objetos de clases, por identidad (salvo que definan equals).

print(3 == 3.0, "a" < "b", [1, 2] == [1, 2], { x: 1 } == { x: 1 })
▶ Probar en el editor

Lógicos

and, or y not. and y or no evalúan el lado derecho si no hace falta, y devuelven uno de los dos valores:

var usuario = null
print(true and false, true or false, not true)
print(usuario or "invitado")
▶ Probar en el editor

Bits

Para números enteros: & (y), | (o), ^ (o exclusivo), ~ (negación), << y >> (desplazamientos).

print(6 & 3, 6 | 3, 6 ^ 3, ~5, 1 << 4, 256 >> 2)  // 2 7 5 -6 16 64
var permisos = 0b101
print((permisos & 0b100) != 0)
▶ Probar en el editor

Null: ?? y ?.

var jugador = { nombre: "Ana", arma: null }
print(jugador.arma ?? "manos")        // valor por defecto si es null
print(jugador.arma?.nombre)           // acceso seguro: null en vez de error
var lista: list? = null
print(lista?.length ?? 0)
▶ Probar en el editor

in

¿Está un elemento en una lista, una clave en un mapa, un texto dentro de otro o un número en un rango?

print(2 in [1, 2, 3], "vida" in { vida: 3 }, "mun" in "mundo", 5 in 1..10)
▶ Probar en el editor

Rangos

a..b va de a a b sin incluir b; a..=b incluye b. En los bucles for, step elige el salto (for i in 10..0 step -3).

print((0..5).toList(), (1..=3).toList(), (5..0).toList())
▶ Probar en el editor

Tubería |>

valor |> f es lo mismo que f(valor): sirve para encadenar pasos de izquierda a derecha en lugar de anidar paréntesis. Si a la derecha hay una llamada, el valor entra como primer argumento.

function doble(x: number): number { return x * 2 }
function sumar(a: number, b: number): number { return a + b }

print(5 |> doble)                 // 10        (doble(5))
print(5 |> doble |> sumar(1))     // 11        (sumar(doble(5), 1))
var pares = [1, 2, 3, 4, 5, 6]
    |> (l => l.filter(n => n % 2 == 0))
    |> (l => l.map(n => n * 10))
print(pares)                      // [20, 40, 60]
▶ Probar en el editor

Una línea que empieza por |> continúa la anterior. La tubería va después de todo lo demás: 2 + 3 |> doble es doble(2 + 3).

Condicional en una expresión

var vida = 0
print(vida > 0 ? "vivo" : "fin de la partida")
▶ Probar en el editor

Precedencia

De mayor a menor (los de arriba se calculan primero). Usa paréntesis cuando dudes.

Operadores
x.y x?.y x[i] f()acceso y llamada
**potencia (por la derecha: 2 ** 3 ** 2 es 2 ** 9; -2 ** 2 es -4)
-x +x !x ~x ++x --x await xunarios
* / %
+ -
.. ..=rangos (0..n + 1 es 0..(n + 1))
<< >>
&
^
`\`
< <= > >= is is not in not in
== !=
not(not a == b es not (a == b))
and
or
??
? :condicional
`\>`tubería
= += -= *= /= %= **= ??=asignación

Operadores en tus propias clases

Una clase puede definir qué hacen +, -, *, /, %, **, las comparaciones, == y obj[i]. Está explicado en Clases: sobrecarga de operadores.