Kotlin
Tutorial Kotlin: Operadores y expresiones
Kotlin operadores y expresiones te enseña todo sobre aritméticos, lógicos y relacionales, mejorando el flujo de datos en tus programas. Fórmate ahora.
Aprende Kotlin GRATIS y certifícateOperadores aritméticos, lógicos y relacionales
En Kotlin, los operadores son símbolos que realizan operaciones sobre uno o más operandos. Los operadores aritméticos, lógicos y relacionales son fundamentales para manipular datos y controlar el flujo de un programa.
Los operadores aritméticos permiten realizar cálculos matemáticos. Los más comunes son:
+
suma-
resta*
multiplicación/
división%
módulo (resto de una división)
Por ejemplo:
val suma = 10 + 5 // Resultado: 15
val resta = 10 - 5 // Resultado: 5
val multiplicacion = 10 * 5 // Resultado: 50
val division = 10 / 5 // Resultado: 2
val modulo = 10 % 3 // Resultado: 1
Es importante tener en cuenta el tipo de datos al realizar divisiones. Si ambos operandos son enteros, el resultado será un entero. Para obtener un resultado con decimales, al menos uno de los operandos debe ser de tipo Double o Float:
val divisionExacta = 10 / 3.0 // Resultado: 3.3333333333333335
Los operadores de asignación combinados simplifican las operaciones aritméticas que afectan a una variable y luego la asignan. Algunos ejemplos son:
+=
suma y asigna-=
resta y asigna*=
multiplica y asigna/=
divide y asigna%=
aplica módulo y asigna
Ejemplo de uso:
var numero = 10
numero += 5 // Equivalente a numero = numero + 5
println(numero) // Resultado: 15
Los operadores relacionales comparan dos valores y devuelven un resultado Boolean (true
o false
). Los principales son:
==
igual a!=
no igual a>
mayor que<
menor que>=
mayor o igual que<=
menor o igual que
Ejemplo:
val a = 10
val b = 5
println(a == b) // Resultado: false
println(a > b) // Resultado: true
Los operadores lógicos permiten combinar expresiones lógicas y devuelven un valor Boolean. Son esenciales para estructuras de control como condicionales y bucles. Los más utilizados son:
&&
conjunción lógica (AND)||
disyunción lógica (OR)!
negación lógica (NOT)
Ejemplo de uso:
val esAdulto = true
val tieneCarnet = false
val puedeConducir = esAdulto && tieneCarnet
println(puedeConducir) // Resultado: false
En este ejemplo, la variable puedeConducir será true
solo si esAdulto y tieneCarnet son true
.
La negación lógica invierte el valor de una expresión Booleana:
val esMenorDeEdad = !esAdulto
println(esMenorDeEdad) // Resultado: false
Kotlin también soporta el operador in
para verificar si un elemento pertenece a una colección o rango:
val numero = 5
val rango = 1..10
println(numero in rango) // Resultado: true
println(numero !in rango) // Resultado: false
El operador in
es muy útil en estructuras de control como bucles for o condicionales if.
Además, Kotlin introduce el operador Elvis ?:
, que proporciona un valor por defecto en caso de que una expresión sea nula:
val nombre: String? = null
val longitud = nombre?.length ?: 0
println(longitud) // Resultado: 0
En este caso, si nombre es null
, longitud tomará el valor después de ?:
, que es 0
.
Finalmente, los operadores de comparación referencial permiten verificar si dos variables apuntan al mismo objeto en memoria:
===
igual referencialmente!==
no igual referencialmente
Ejemplo:
val texto1 = "Kotlin"
val texto2 = "Kotlin"
println(texto1 == texto2) // Resultado: true (contenido igual)
println(texto1 === texto2) // Resultado: false (referencias diferentes)
En este ejemplo, aunque texto1 y texto2 tienen el mismo contenido, no son el mismo objeto en memoria.
Precedencia y asociatividad de operadores
En Kotlin, la precedencia de operadores determina el orden en el que se evalúan las expresiones que contienen múltiples operadores. La asociatividad define el orden en el que se agrupan los operadores con la misma precedencia. Comprender estos conceptos es fundamental para evitar resultados inesperados en cálculos y expresiones lógicas.
Los operadores con mayor precedencia se evalúan antes que los de menor precedencia. Si una expresión contiene operadores del mismo nivel de precedencia, la asociatividad determina el orden de evaluación: asociatividad izquierda significa que se evalúa de izquierda a derecha, mientras que asociatividad derecha implica una evaluación de derecha a izquierda.
Por ejemplo, considera la siguiente expresión aritmética:
val resultado = 10 + 5 * 2
En este caso, el operador *
(multiplicación) tiene mayor precedencia que el operador +
(suma). Por lo tanto, la multiplicación se evalúa primero:
5 * 2
produce10
.- Luego, se suma
10 + 10
, dando un resultado de20
.
Si se desea cambiar el orden de evaluación, se pueden utilizar paréntesis para alterar la precedencia:
val resultado = (10 + 5) * 2 // Resultado: 30
Ahora, la suma dentro de los paréntesis se evalúa primero, y luego el resultado se multiplica por 2
.
La tabla de precedencia en Kotlin, de mayor a menor, incluye:
- Operadores de incremento y decremento:
++
y--
. - Operadores unarios:
+
,-
,!
,~
. - Cast seguro:
as
. - Multiplicación y división:
*
,/
,%
. - Suma y resta:
+
,-
. - Operadores de rango:
..
. - Operadores de comparación:
<
,>
,<=
,>=
. - Igualdad:
==
,!=
. - Operadores en intervalo:
in
,!in
. - Operadores lógicos AND y OR bit a bit:
&
,|
,^
. - Operadores lógicos:
&&
,||
. - Operadores de asignación:
=
,+=
,-=
,*=
,/=
,%=
.
La asociatividad en Kotlin generalmente es de izquierda a derecha. Sin embargo, algunos operadores, como los de asignación (=
), son asociativos a la derecha. Esto significa que en una expresión como:
val z = 5
val y = z
val x = y
La asignación se realiza de la siguiente manera: primero z
se asigna a 5
, luego y
se asigna a z
, y finalmente x
se asigna a y
.
Es crucial prestar atención al usar operadores lógicos. Por ejemplo:
val resultado = true || false && false
El operador &&
tiene mayor precedencia que ||
, por lo que se evalúa primero:
false && false
producefalse
.- Luego,
true || false
producetrue
.
Si se desea que el operador ||
se evalúe primero, se pueden usar paréntesis:
val resultado = (true || false) && false // Resultado: false
Los operadores unarios como ++
y --
también tienen consideraciones de precedencia. Cuando se utilizan antes del operando (forma prefija), el incremento o decremento ocurre antes de la evaluación de la expresión. En la forma postfija, ocurre después:
var x = 5
val y = x++ // y = 5, x = 6
var m = 5
val n = ++m // n = 6, m = 6
Entender la precedencia y asociatividad ayuda a escribir expresiones más claras y evita errores. Sin embargo, es una buena práctica utilizar paréntesis para hacer explícito el orden de evaluación, mejorando la legibilidad del código:
val resultado = (a + b) * (c - d) / e
De esta manera, otros desarrolladores podrán comprender fácilmente la intención detrás de las operaciones sin necesidad de recordar todas las reglas de precedencia.
Conversión y casting de tipos
En Kotlin, la conversión de tipos es un proceso esencial para manejar diferentes tipos de datos de manera segura y eficiente. A diferencia de algunos lenguajes donde las conversiones pueden ser implícitas, en Kotlin las conversiones numéricas deben realizarse de forma explícita mediante funciones específicas.
Para convertir un tipo numérico a otro, se utilizan funciones como toByte()
, toShort()
, toInt()
, toLong()
, toFloat()
, toDouble()
, entre otras. Por ejemplo:
val numeroEntero: Int = 42
val numeroDouble: Double = numeroEntero.toDouble()
En este ejemplo, se convierte el valor entero 42
a un valor de tipo Double
utilizando la función toDouble()
.
Es importante tener en cuenta que las conversiones pueden llevar a pérdidas de precisión o información, especialmente al convertir de tipos de mayor capacidad a tipos de menor capacidad. Por ello, es fundamental realizar conversiones conscientes para evitar errores en el programa.
Kotlin también ofrece el concepto de casting para trabajar con tipos más generales o específicos dentro de una jerarquía de clases. El operador is
se utiliza para comprobar si un objeto es de un tipo determinado:
fun identificar(objeto: Any) {
if (objeto is String) {
println("Es una cadena de texto de longitud ${objeto.length}")
}
}
En este ejemplo, se verifica si objeto
es una instancia de String
. Si la condición es verdadera, Kotlin realiza un smart cast automáticamente, permitiendo acceder a las propiedades y métodos de String
sin necesidad de un casting explícito.
Para realizar un casting explícito, se utiliza el operador as
. Este operador intenta convertir una instancia a un tipo específico. Si la conversión no es posible, lanzará una excepción ClassCastException
:
val cualquierObjeto: Any = "Kotlin"
val cadena: String = cualquierObjeto as String
Si existe la posibilidad de que el casting falle, es recomendable utilizar el casting seguro con as?
, que devuelve null
en caso de no poder realizar la conversión:
val numero: Int? = cualquierObjeto as? Int // numero será null
El uso de as?
es esencial para evitar excepciones y manejar de forma segura posibles conversiones fallidas.
Además, Kotlin incorpora funciones para trabajar con tipos genéricos y herencia. Cuando se trabaja con una jerarquía de clases, es común necesitar comprobar el tipo de un objeto y actuar en consecuencia. Por ejemplo:
open class Vehiculo
class Coche : Vehiculo()
class Moto : Vehiculo()
fun describir(vehiculo: Vehiculo) {
when (vehiculo) {
is Coche -> println("Es un coche")
is Moto -> println("Es una moto")
else -> println("Tipo de vehículo desconocido")
}
}
En este caso, utilizamos el operador is
dentro de una expresión when
para identificar el tipo específico del objeto vehiculo
.
Para evitar errores de casting y mejorar la seguridad del código, es buena práctica aprovechar el sistema de tipos de Kotlin y sus mecanismos de smart casting y comprobaciones de tipo en tiempo de compilación.
Cuando se trabaja con tipos nullables, es esencial manejar las posibles referencias nulas para evitar excepciones NullPointerException
. Kotlin proporciona el operador de llamada segura ?.
y el operador Elvis ?:
para facilitar este manejo:
val cadenaNula: String? = null
val longitud: Int = cadenaNula?.length ?: 0
En este ejemplo, si cadenaNula
es null
, longitud
tomará el valor 0
. Esto permite manejar de forma elegante y segura las referencias nulas sin necesidad de realizar múltiples comprobaciones.
Entender y utilizar correctamente la conversión y casting de tipos en Kotlin es fundamental para escribir código robusto y libre de errores. Aprovechar las herramientas que ofrece el lenguaje, como las funciones de conversión, los operadores is
y as
, y los mecanismos de manejo de tipos nullables, mejora la calidad y fiabilidad de las aplicaciones desarrolladas.
Ejercicios de esta lección Operadores y expresiones
Evalúa tus conocimientos de esta lección Operadores y expresiones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Clases genéricas con varianza y restricciones
Introducción a las corutinas
Uso de asincronía con suspend, async y await
Formateo de cadenas texto
Uso de monads y manejo funcional de errores
Declaración y uso de variables y constantes
Uso de la concurrencia funcional con corutinas
Operaciones en colecciones
Uso de clases y objetos en Kotlin
Evaluación Kotlin
Funciones de orden superior y expresiones lambda en Kotlin
Herencia y polimorfismo en Kotlin
Inmutabilidad y datos inmutables
Uso de funciones parciales y currificaciones
Primer programa en Kotlin
Introducción a la programación funcional
Introducción a Kotlin
Uso de operadores y expresiones
Sistema de inventario de tienda
Uso de data classes y destructuring
Composición de funciones
Uso de interfaces y clases abstractas
Simulador de conversión de monedas
Programación funcional y concurrencia
Creación y uso de listas, conjuntos y mapas
Transformación en monads y functors
Crear e invocar funciones
Uso de las estructuras de control
Todas las lecciones de Kotlin
Accede a todas las lecciones de Kotlin y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Kotlin
Introducción Y Entorno
Instalación Y Primer Programa De Kotlin
Introducción Y Entorno
Tipos De Datos, Variables Y Constantes
Sintaxis
Operadores Y Expresiones
Sintaxis
Cadenas De Texto Y Manipulación
Sintaxis
Estructuras De Control
Sintaxis
Funciones Y Llamada De Funciones
Sintaxis
Clases Y Objetos
Programación Orientada A Objetos
Herencia Y Polimorfismo
Programación Orientada A Objetos
Interfaces Y Clases Abstractas
Programación Orientada A Objetos
Data Classes Y Destructuring
Programación Orientada A Objetos
Tipos Genéricos Y Varianza
Programación Orientada A Objetos
Listas, Conjuntos Y Mapas
Estructuras De Datos
Introducción A La Programación Funcional
Programación Funcional
Funciones De Primera Clase Y De Orden Superior
Programación Funcional
Inmutabilidad Y Datos Inmutables
Programación Funcional
Composición De Funciones
Programación Funcional
Monads Y Manejo Funcional De Errores
Programación Funcional
Operaciones Funcionales En Colecciones
Programación Funcional
Transformaciones En Monads Y Functors
Programación Funcional
Funciones Parciales Y Currificación
Programación Funcional
Introducción A Las Corutinas
Coroutines Y Asincronía
Asincronía Con Suspend, Async Y Await
Coroutines Y Asincronía
Concurrencia Funcional
Coroutines Y Asincronía
Evaluación
Evaluación
Certificados de superación de Kotlin
Supera todos los ejercicios de programación del curso de Kotlin y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el uso de operadores aritméticos, lógicos y relacionales en Kotlin.
- Aplicar operadores de asignación combinados para simplificar el código.
- Controlar el flujo del programa utilizando operadores lógicos.
- Diferenciar entre operadores de comparación de valores y referenciales.
- Usar correctamente la precedencia y asociatividad de operadores para evitar errores en cálculos.
- Implementar conversiones y casting de tipos con seguridad y eficacia.