Saltar al contenido principal

Naming

Rust suele usar UpperCamelCase para type-level (types y traits) y snake_case para value-level

En UpperCamelCase las siglas y contracciones de palabras compuestas cuentan como una sola palabra

  • Usar Uuid en lugar de UUID
  • Usize en lugar de USize
  • Stdin en lugar de StdIn

En snake_case los acrónimos y contracciones se escriben en minúsculas is_xid_start

En snake_case o SCREAMING_SNAKE_CASE, una "palabra" nunca debe constar de una sola letra, a menos que sea la última.

  • btree_map en lugar de b_tree_map
  • PI_2 en lugar de PI2

Los nombres de crates no deben usar -rs ni -rust como sufijo o prefijo. ¡Todos los crates son Rust!. No sirve de nada recordarles esto constantemente a los usuarios.

ItemConvención
Cratesunclear
Modulessnake_case
TypesUpperCamelCase
TraitsUpperCamelCase
Enum variantsUpperCamelCase
Functionssnake_case
Methodssnake_case
General constructorsnew or with_more_details
Conversion constructorsfrom_some_other_type
Macrossnake_case!
Local variablessnake_case
StaticsSCREAMING_SNAKE_CASE
ConstantsSCREAMING_SNAKE_CASE
Type parametersconcise UpperCamelCase, usually single uppercase letter: T
Lifetimesshort lowercase, usually a single letter: 'a'de'src
Featuresunclear but see C-FEATURE

Ad-hoc

Las conversiones Ad-hoc siguen las convenciones is_, to_, into_ (C-CONV)

Las conversiones deben proporcionarse como métodos, con nombres prefijados como los siguientes:

PrefixCostOwnership
as_Freeborrowed -> borrowed
to_Expensiveborrowed -> borrowed, borrowed -> owned (non-Copy types), owned -> owned (Copy types)
into_Variableowned -> owned (non-Copy types)

Ad-hoc En programación, se usa para referirse a soluciones, estructuras o métodos diseñados específicamente para una situación particular, en lugar de ser generalizados o reutilizables en múltiples contextos.

En el caso de las conversiones ad-hoc, nos referimos a métodos de conversión diseñados específicamente para transformar un tipo de dato en otro dentro de un contexto particular. No forman parte de una conversión implícita o automática del lenguaje, sino que se implementan de manera explícita para casos específicos.

Por ejemplo, en Rust, el método str::as_bytes() convierte una &str en una &[u8] de manera específica, sin definir una conversión automática entre estos tipos en todas las circunstancias.

Si el mutcalificador en el nombre de un método de conversión forma parte del tipo de retorno, debe aparecer como aparecería en el tipo. Por ejemplo, Vec::as_mut_slice devuelve una porción mut; hace lo que indica. Este nombre es preferible a as_slice_mut.

// Return type is a mut slice. 
fn as_mut_slice(&mut self) -> &mut [T];

as_ - Conversiones gratuitas (sin costo significativo)

Se usa para conversiones sin costo que simplemente reinterpretan o muestran una vista diferente de los mismos datos.

  • Comportamiento: De borrowed a borrowed, prestado a prestado, (&T&U)
  • Costo: Sin costo significativo, generalmente solo un cambio de perspectiva
  • Ejemplo: str::as_bytes() - simplemente ve la misma memoria como bytes UTF-8 sin hacer ningún trabajo, (&str -> &[u8])

to_ - Conversiones costosas

Se utiliza cuando la conversión implica un costo mayor, ya sea por validaciones o asignaciones, y la semántica de propiedad puede variar según si el tipo es Copy o no.

Comportamiento

  • De borrowed (prestado) a borrowed (prestado) (&T&U)
  • De borrowed (prestado) a owned (propio) (&TU)
  • De owned (propio) a owned (propio) para tipos Copy (TU donde T: Copy)

Costo Computacionalmente significativo (puede implicar operaciones costosas en tiempo o recursos, como validaciones o asignaciones de memoria)

Ejemplos str::to_lowercase() produce el equivalente en minúsculas Unicode correcto de una cadena, lo que implica iterar los caracteres de la cadena y puede requerir la asignación de memoria. La entrada es un &str prestado y la salida es una cadena propia. &str -> String

Path::to_str realiza una comprobación costosa para asegurar que los bytes de una ruta del sistema operativo sean UTF-8. Tanto la entrada como la salida son prestadas. No sería correcto llamarlo as_str, ya que este método tiene un coste considerable en tiempo de ejecución.

f64::to_radians() convierte un número de grados a radianes, se usa to_ en lugar de into_., no se justifica pasar una referencia &f64, ya que f64 es fácil de copiar. Llamar a la función into_radians sería engañoso, ya que la entrada no se consume.

into_ - Conversiones que consumen el valor original

Se emplea para conversiones que consumen el valor original y devuelven uno nuevo, sin la intención de preservar el original.

Comportamiento De owned (propio) a owned (propio) para tipos no-Copy (TU donde T no es Copy). Toma la propiedad del valor de entrada (owned) y devuelve otro valor owned

Costo Variable, puede ser gratuito o costoso

Ejemplo String::into_bytes() consume un String para extraer el Vec<u8> interno sin realizar copias adicionales.

BufReader::into_inner() toma posesión de un lector con búfer y extrae el lector subyacente, que está libre. Los datos del búfer se descartan.

BufWriter::into_inner() toma posesión de un escritor con búfer y extrae el escritor subyacente, lo que requiere un vaciado potencialmente costoso de cualquier búfer.

Getters

  • Los nombres de los getters siguen la convención de Rust (C-GETTER)
  • Con algunas excepciones, el prefijo get_ no se utiliza para getters en el código Rust.
pub struct S {
first: First,
second: Second,
}

impl S {
// Not get_first.
pub fn first(&self) -> &First {
&self.first
}

// Not get_first_mut, get_mut_first, or mut_first.
pub fn first_mut(&mut self) -> &mut First {
&mut self.first
}
}

El nombre get se usa solo cuando existe un único y obvio elemento que un getter podría obtener razonablemente. Por ejemplo, Cell::get accede al contenido de un Cell.

Para los getters que realizan validación en tiempo de ejecución, como la comprobación de límites, considere agregar variantes inseguras _unchecked.

fn get(&self, index: K) -> Option<&V>;
fn get_mut(&mut self, index: K) -> Option<&mut V>;
unsafe fn get_unchecked(&self, index: K) -> &V;
unsafe fn get_unchecked_mut(&mut self, index: K) -> &mut V;

La diferencia entre los getters y las conversiones ( C-CONV ) puede ser sutil y no siempre clara. Por ejemplo, TempDir::path se puede entender como un getter para la ruta del sistema de archivos del directorio temporal, mientras que TempDir::into_path es una conversión que transfiere la responsabilidad de eliminar el directorio temporal al invocador. Dado que path es un getter, no sería correcto llamarlo get_path o as_path.