Saltar al contenido principal

Seguridad ante Nulos y Opcionales

Manejar valores null/nil es una fuente común de errores. Así es como los diferentes lenguajes abordan la seguridad ante nulos.

Tipos Nullable y Opcionales​

// null and undefined are distinct
let a = null; // Intentionally empty
let b = undefined; // Not yet assigned
let c; // undefined

// Checking for null/undefined
if (value === null) { }
if (value === undefined) { }
if (value == null) { } // checks both null & undefined

// Nullish coalescing (??)
const name = user ?? "default";
const age = data.age ?? 0;

// Optional chaining (?.)
const city = user?.address?.city;
const first = arr?.[0];
const result = func?.();

// Nullish coalescing assignment
let x = null;
x ??= "default"; // x is now "default"

// Logical OR (includes falsy values)
const name2 = user || "default"; // "" -> "default"
const name3 = user ?? "default"; // "" -> ""

Puntos Clave​

  • Tipos Option/Optional -- Rust (Option<T>), Swift (T?), Zig (?T) y Java (Optional<T>) proporcionan tipos opcionales explícitos en lugar de referencias anulables. En Rust, let x: Option<i32> = Some(42) o None -- no existe null; usas match, if let o unwrap_or(0). var name: String? = nil de Swift y var value: ?i32 = null de Zig hacen de la opcionalidad parte del tipo. Optional<String> opt = Optional.ofNullable(name) de Java envuelve valores anulables. Estos tipos te obligan a manejar la ausencia explícitamente. Elige Option/Optional cuando quieras aplicación en tiempo de compilación; usa referencias anulables (JavaScript, Python, C) cuando prefieras flexibilidad y verificaciones en tiempo de ejecución.

  • Operadores de coalescencia nula -- La mayoría de los lenguajes soportan ?? para valores por defecto: const name = user ?? "default" en JavaScript, $name = $user ?? "default" en PHP, string name = user ?? "default" en C#, let result = name ?? "default" en Swift y const result = value orelse 0 en Zig. Estos ignoran valores falsy como "" o 0 (a diferencia de || en JavaScript). Go no tiene ??; usas if user != nil { name = user.Name } else { name = "default" } o funciones auxiliares. Elige lenguajes con ?? cuando necesites valores por defecto seguros con frecuencia; en Go, encapsula los valores por defecto en pequeñas funciones auxiliares.

  • Lenguajes que eliminan null -- Rust no tiene null; los valores opcionales usan Option<T>. Swift y Zig usan tipos opcionales como mecanismo principal: en Swift, String? es distinto de String, y desenvolver con ! o if let es explícito. ?T de Zig obliga a usar orelse o if para manejar null. Esto evita el "error del billón de dólares" de las desreferencias nulas. Python, JavaScript, Java y C permiten null/None/undefined en cualquier lugar, lo que lleva a NullPointerException o TypeError en tiempo de ejecución. Si eliminar errores de nulos es una prioridad, elige Rust; Swift y Zig ofrecen un manejo fuerte de opcionales con menos estrictez que Rust.

  • Navegación segura -- El encadenamiento opcional (?.) en JavaScript, PHP, C#, Swift y Ruby previene errores de desreferencia nula al recorrer estructuras anidadas. Por ejemplo, user?.address?.city retorna undefined o nil si algún eslabón es nulo en lugar de lanzar una excepción. arr?.[0] y func?.() de JavaScript extienden esto a arrays y llamadas. Sin ?., escribes user && user.address && user.address.city (JavaScript) o verificaciones if anidadas. Go no tiene ?.; verificas if user != nil && user.Address != nil { city = user.Address.City }. Prefiere ?. cuando trabajes con datos profundamente anidados y de tipado flexible (APIs, configuraciones).

  • Asignación de coalescencia nula -- JavaScript (x ??= "default"), PHP ($name ??= "default") y C# (name ??= "default") asignan un valor por defecto solo cuando la variable es null o undefined. Esto mantiene el código conciso al inicializar campos opcionales. Go y Rust requieren if o match explícitos. Usa ??= cuando tengas configuración opcional o valores por defecto perezosos; en Go y Rust, usa patrones Option/if para mayor claridad.