Rust

Equivalencias idiomáticas entre Kotlin y Rust. Kotlin se presenta como referencia en cada concepto.

Tipos paramétricos y convenciones del lenguaje

Genéricos, operadores y rangos cambian de sintaxis entre ecosistemas, pero las preguntas de diseño detrás son las mismas: qué varía, qué se comprueba y cuándo.

Equivalencia desde Kotlin

Genéricos y varianza

Cercana

En Rust, propiedad y préstamos; no subtipado nominal de tipos de dominio expresa la responsabilidad del fixture: Source<T> produce valores y Sink<T> los consume sin mezclar ambas responsabilidades.

Referencia Kotlin: Source<out T> es covariante y Sink<in T> es contravariante.

Mecanismo
propiedad y préstamos; no subtipado nominal de tipos de dominio
Riesgo de diseño
Copiar la sintaxis de Kotlin en vez de usar propiedad y préstamos; no subtipado nominal de tipos de dominio.
Recomendación
Expón el contrato del fixture y usa propiedad y préstamos; no subtipado nominal de tipos de dominio solo para la garantía que realmente ofrece.

Diferencias relevantes

  • La varianza puede declararse, proyectarse en el uso o no tener una noción de subtipado equivalente.
  • La forma idiomática de Rust debe conservarse aunque la sintaxis difiera de Kotlin.

Source<T> produce valores y Sink<T> los consume sin mezclar ambas responsabilidades.

trait Source<T> { fn get(&self) -> &T; }
// Rust expresa seguridad con ownership y borrowing, no con subtipado Animal/Cat.

Fuentes

Equivalencia desde Kotlin

Operadores

Cercana

En Rust, método contains, como en RangeInclusive::contains de la biblioteca estándar expresa la responsabilidad del fixture: Comprueba si un precio de 79.9 cae dentro de un rango válido entre 50.0 y 100.0.

Referencia Kotlin: operator fun contains permite escribir price in range para una pertenencia definida por el dominio.

Mecanismo
método contains, como en RangeInclusive::contains de la biblioteca estándar
Riesgo de diseño
Copiar la sintaxis de Kotlin en vez de usar método contains, como en RangeInclusive::contains de la biblioteca estándar.
Recomendación
Expón el contrato del fixture y usa método contains, como en RangeInclusive::contains de la biblioteca estándar solo para la garantía que realmente ofrece.

Diferencias relevantes

  • Muy pocos lenguajes permiten definir el operador de pertenencia (in) sobre un tipo propio; la mayoría exige un método con nombre como contains.
  • La forma idiomática de Rust debe conservarse aunque la sintaxis difiera de Kotlin.

Comprueba si un precio de 79.9 cae dentro de un rango válido entre 50.0 y 100.0.

let price_range = 50.0..=100.0;
price_range.contains(&79.9);

Sin operador de invocación definible por la persona usuaria: una clausura ya es invocable con ().

let is_above_minimum = |price: f64| price >= 10.0;
is_above_minimum(79.9);

Fuentes

Equivalencia desde Kotlin

Rangos

Cercana

En Rust, rango inclusivo 1..=limit expresa la responsabilidad del fixture: Itera los enteros desde 1 hasta limit, incluyendo limit.

Referencia Kotlin: 1..limit representa una progresión de extremos inclusivos.

Mecanismo
rango inclusivo 1..=limit
Riesgo de diseño
Copiar la sintaxis de Kotlin en vez de usar rango inclusivo 1..=limit.
Recomendación
Expón el contrato del fixture y usa rango inclusivo 1..=limit solo para la garantía que realmente ofrece.

Diferencias relevantes

  • Un rango puede ser una colección reutilizable, un iterable perezoso o solo una forma de construir un bucle.
  • La forma idiomática de Rust debe conservarse aunque la sintaxis difiera de Kotlin.

Itera los enteros desde 1 hasta limit, incluyendo limit.

for value in 1..=limit { println!("{value}"); }

Fuentes