Operadores de Dart
Los operadores son símbolos en un programa que realizan cálculos, comparaciones y juicios lógicos.
Este capítulo presenta sistemáticamente los distintos tipos de operadores en Dart, incluyendo aritméticos, relacionales, lógicos, de asignación, condicionales y verificación de tipos.
Operadores aritméticos
Los operadores aritméticos se utilizan para realizar operaciones matemáticas básicas.
Ejemplo
int a = 10;
int b = 3;
print('a = $a, b = $b');
print('Suma a + b = ${a + b}'); // 13
print('Resta a - b = ${a - b}'); // 7
print('Multiplicación a * b = ${a * b}'); // 30
print('División a / b = ${a / b}'); // 3.333... (el resultado es double)
print('División entera a ~/ b = ${a ~/ b}'); // 3 (parte entera, se descartan los decimales)
print('Resto a % b = ${a % b}'); // 1 (operación de módulo)
print('Negación -a = ${-a}'); // -10 (signo negativo unario)
}
a = 10, b = 3 加法 a + b = 13 减法 a - b = 7 乘法 a * b = 30 除法 a / b = 3.3333333333333335 整除 a ~/ b = 3 取余 a % b = 1 取反 -a = -10
Nota: el operador / siempre devuelve un tipo double, incluso si ambos operandos son int y son exactamente divisibles. Si solo necesitas un resultado entero, usa el operador de división entera ~/.
Operadores de incremento y decremento
Como en la mayoría de los lenguajes de la familia C, Dart admite ++ (incremento) y -- (decremento).
Ejemplo
int count = 0;
// ++ prefijo: primero incrementa, luego usa
print('++ prefijo: ${++count}'); // 1
// ++ sufijo: primero usa, luego incrementa
print('++ sufijo: ${count++}'); // 1 (en este momento count sigue siendo 1)
print('Ahora count = $count'); // 2
// El decremento es similar
print('-- prefijo: ${--count}'); // 1
print('-- sufijo: ${count--}'); // 1
print('Ahora count = $count'); // 0
}
前置 ++: 1 后置 ++: 1 现在 count = 2 前置 --: 1 后置 --: 1 现在 count = 0
El incremento/decremento prefijo y sufijo tienen el mismo efecto cuando se usan solos, pero se comportan de manera diferente en expresiones. Se recomienda a los principiantes evitar usarlos en expresiones; escribirlos en una línea separada es más claro.
Operadores relacionales
Los operadores relacionales se utilizan para comparar dos valores; el resultado es un valor bool.
| Operador | Significado | Ejemplo | Resultado |
|---|---|---|---|
| == | Igual a | 5 == 5 | true |
| != | No igual a | 5 != 3 | true |
| > | Mayor que | 5 > 3 | true |
| < | Menor que | 5 < 3 | false |
| >= | Mayor o igual que | 5 >= 5 | true |
| <= | Menor o igual que | 3 <= 5 | true |
Ejemplo
int ejemploScore = 95;
int passLine = 60;
print('Puntuación: $ejemploScore, línea de aprobado: $passLine');
print('¿Aprobado? ${ejemploScore >= passLine}');
print('¿Puntuación perfecta? ${ejemploScore == 100}');
// Las cadenas también se pueden comparar
String a = 'apple';
String b = 'banana';
print("'$a' == '$b'? ${a == b}");
// == determina si los valores son iguales
String c = 'EJEMPLO';
String d = 'EJEMPLO';
print("'$c' == '$d'? ${c == d}"); // true (el contenido es el mismo)
}
分数: 95, 及格线: 60 及格了吗? true 满分了吗? false 'apple' == 'banana'? false 'EJEMPLO' == 'EJEMPLO'? true
En Dart, == compara si los valores de dos objetos son iguales, no la dirección de referencia. Esto es diferente de Java: en Dart no necesitas usar el método equals() para comparar cadenas.
Operadores lógicos
Los operadores lógicos se utilizan para combinar varias expresiones bool, normalmente en evaluaciones condicionales.
| Operador | Significado | Descripción |
|---|---|---|
| && | Y lógico (AND) | Devuelve true solo si ambos lados son true |
| || | O lógico (OR) | Devuelve true si al menos un lado es true |
| ! | NO lógico (NOT) | Invierte el valor: true se convierte en false, false en true |
Ejemplo
bool isLoggedIn = true;
bool isAdmin = false;
// && Y: ambos son true
print('Iniciado sesión y es administrador: ${isLoggedIn && isAdmin}'); // false
// || O: al menos uno es true
print('Iniciado sesión o es administrador: ${isLoggedIn || isAdmin}'); // true
// ! NO: invierte
print('No iniciado sesión: ${!isLoggedIn}'); // false
// Evaluación de cortocircuito: si el lado izquierdo ya determina el resultado, el derecho no se ejecuta
int age = 20;
// age > 18 ya es true, pero aún hay que evaluar el lado derecho
print('Adulto y con permisos: ${age >= 18 && isAdmin}');
// age < 18 ya es false, el lado derecho de && se omite
print('Menor de edad y con permisos: ${age < 18 && isAdmin}');
}
登录且是管理员: false 登录或是管理员: true 未登录: false 成年且有权限: false 未成年且有权限: false
Dart utilizaEvaluación de cortocircuito (Short-circuit Evaluation): para &&, si el lado izquierdo es false, el derecho no se evalúa; para ||, si el lado izquierdo es true, el derecho no se evalúa.
Esta característica se puede usar para evitar problemas de puntero nulo.
Ejemplo
Aplicación práctica de la evaluación de cortocircuito:
String? username;
// Verificación segura: username no es null y su longitud es mayor que 3
// Si username es null, el lado derecho de && no se ejecuta, evitando errores de puntero nulo
if (username != null && username.length > 3) {
print('Nombre de usuario válido');
} else {
print('Nombre de usuario inválido o demasiado corto');
}
}
Nombre de usuario no válido o demasiado corto
Operadores de asignación
El operador de asignación básico = ya lo conoces bien.
Dart también proporciona operadores de asignación compuesta para simplificar las operaciones comunes de "calcular y luego asignar".
| Operador | Escritura equivalente | Ejemplo (cuando a=10) |
|---|---|---|
| += | a = a + b | a += 3 → 13 |
| -= | a = a - b | a -= 3 → 7 |
| *= | a = a * b | a *= 3 → 30 |
| /= | a = a / b | a /= 2 → 5.0 |
| ~/= | a = a ~/ b | a ~/= 3 → 3 |
| %= | a = a % b | a %= 3 → 1 |
Ejemplo
int score = 0;
// Cada respuesta correcta suma 10 puntos
score += 10;
print('Acierto en la pregunta 1: $score');
score += 10;
print('Acierto en la pregunta 2: $score');
// Respuesta incorrecta resta 5 puntos
score -= 5;
print('Fallo en 1 pregunta: $score');
// La puntuación se duplica
score *= 2;
print('Bonus duplicado: $score');
print('Puntuación final de EJEMPLO: $score');
}
答对第1题: 10 答对第2题: 20 答错1题: 15 奖励翻倍: 30 EJEMPLO 最终得分: 30
Operadores condicionales: ?? y ??=
Estos dos operadores están diseñados específicamente para manejar valores null y son una parte importante del sistema de seguridad de nulos de Dart.
?? Operador de fusión de nulos
Si la expresión de la izquierda no es null, devuelve el valor de la izquierda; de lo contrario, devuelve el valor de la derecha.
??= Operador de asignación de nulos
Si la variable actualmente es null, se le asigna el valor de la derecha; de lo contrario, permanece sin cambios.
Ejemplo
// ?? Fusión de nulos
String? nickname;
String displayName = nickname ?? 'Usuario de EJEMPLO';
print(displayName); // Usuario de EJEMPLO
nickname = 'Xiao R';
displayName = nickname ?? 'Usuario de EJEMPLO';
print(displayName); // Xiao R
// La fusión ?? encadenada también funciona
String? a;
String? b;
String result = a ?? b ?? 'Valor predeterminado';
print(result); // Valor predeterminado
// ??= Asignación de nulos
int? count;
count ??= 0; // count es null, se asigna 0
print(count); // 0
count ??= 100; // count ya es 0 (no null), no se asigna
print(count); // 0 (sin cambios)
}
EJEMPLO 用户 小R 默认值 0 0
Operador condicional ternario ? :
Es el único operador de tres operandos en Dart y es una versión concisa de if-else.
Ejemplo
int score = 75;
// Sintaxis: condición ? valor si es verdadero : valor si es falso
String result = score >= 60 ? 'Aprobado' : 'Reprobado';
print('Resultado del examen de EJEMPLO: $result');
// Se puede anidar (pero no se recomienda más de dos niveles; la legibilidad empeora)
String grade = score >= 90 ? 'Excelente' : score >= 60 ? 'Aprobado' : Suspenso;
print('Calificación: $grade');
}
EJEMPLO 考试结果: 及格 评级: 及格
Operadores de verificación de tipo: is y as
is se usa para comprobar si un objeto pertenece a un tipo; as se usa para la conversión de tipos.
Ejemplo
// is: comprobación de tipo
var name = 'EJEMPLO';
print('¿Es name un String? ${name is String}'); // true
print('¿Es name un int? ${name is int}'); // false
// is!: no es de un tipo
print('¿No es name un int? ${name is! int}'); // true
// as: conversión de tipos
Object obj = 'Hello, Dart!';
// Convertir el tipo Object a String para poder usar los métodos de String
String str = obj as String;
print(str.toUpperCase());
// Comprobación de tipo segura + conversión
Object maybeString = 42;
if (maybeString is String) {
// En la rama donde is evalúa true, la variable se "promociona" automáticamente a ese tipo
print(maybeString.length); // No se necesita conversión con as
} else {
print('No es un string, el valor es: $maybeString');
}
}
name 是 String 吗? true name 是 int 吗? false name 不是 int 吗? true HELLO, DART! 不是字符串,值是: 42
Prioriza el uso de is para la comprobación de tipos. Dentro de la rama condicional donde is es true, Dart promueve automáticamente la variable al tipo objetivo (Type Promotion), sin necesidad de usar as para una conversión forzada. as solo se usa cuando "estás seguro del tipo pero el compilador no puede inferirlo".
Resumen de precedencia de operadores
Cuando una expresión tiene múltiples operadores, Dart los evalúa según su prioridad, de mayor a menor.
Si no estás seguro de la prioridad, la opción más segura esusar paréntesis para especificar claramente el orden de cálculo。
| Prioridad | Operador | Descripción |
|---|---|---|
| La más alta | () [] . ?. | Paréntesis, subíndices, acceso a miembros |
| ! ~ - ++ -- | Operadores unarios | |
| * / % ~/ | Multiplicación, división, módulo | |
| + - | Suma y resta | |
| < <= > >= | Comparación relacional | |
| == != | Comprobación de igualdad | |
| && | Y lógico | |
| || | O lógico | |
| ?? | Coalescencia de nulos | |
| ? : | Condicional ternario | |
| = += -= *= etc. | Asignación (la más baja) |
Ejemplo
// No depender de la prioridad: usar paréntesis para expresar claramente la intención
int result = ((10 + 5) * 2) - (8 ~/ 3);
print('Resultado del cálculo: $result'); // 28
// Sin paréntesis, el resultado podría ser completamente diferente
// El resultado de 10 + 5 * 2 - 8 ~/ 3 sería 18 (primero multiplicación/división, luego suma/resta)
int result2 = 10 + 5 * 2 - 8 ~/ 3;
print('Sin paréntesis: $result2'); // 18
}
计算结果: 28 不加括号: 18Otras extensiones