rust - geertz - ¿Cuál es la diferencia entre el yo y el yo?
geertz 2003 (2)
No me he encontrado con Self
en la documentación, solo en el código fuente. La documentación solo usa el self
.
doc.rust-lang.org/reference/types.html#self-types es el tipo del objeto actual. Puede aparecer en un trait
o en un impl
, pero aparece más a menudo en un trait
en el que es un suplente para cualquier tipo que termine implementando el trait
(que se desconoce cuando se define el trait
):
trait Clone {
fn clone(&self) -> Self;
}
Si luego implemento el Clone
:
impl Clone for MyType {
// I can use either the concrete type (known here)
fn clone(&self) -> MyType;
// Or I can use Self again, it''s shorter after all!
fn clone(&self) -> Self;
}
También podría usarlo en una impl
regular si soy flojo (¡es más corto!):
impl MySuperLongType {
fn new(a: u32) -> Self { ... }
}
self
es el nombre utilizado en un trait
o impl
para el primer argumento de un método. Usar otro nombre es posible, sin embargo, hay una diferencia notable:
- Si se usa
self
, la función introducida es un método. - Si usa cualquier otro nombre, la función introducida es una función asociada.
En Rust, no hay implícito this
argumento pasado a los métodos de un tipo: tiene que pasar explícitamente el "objeto actual" como parámetro del método. Esto resultaría en:
impl MyType {
fn doit(this: &MyType, a: u32) { ... }
}
Como hemos visto, como una forma más corta, esto también podría ser (aún detallado):
impl MyType {
fn doit(this: &Self, a: u32) { ... }
}
Que en realidad es lo que &self
reduce a debajo de las sábanas.
impl MyType {
fn doit(&self, a: u32) { ... }
}
Así la tabla de correspondencia:
self => self: Self
&self => self: &Self
&mut self => self: &mut Self
Sin embargo, la forma de invocar esas funciones cambia:
impl MyType {
fn doit(&self, a: u32) {
// ...
}
fn another(this: &Self, a: u32) {
// ...
}
}
fn main() {
let m = MyType;
// Both can be used as an associated function
MyType::doit(&m, 1);
MyType::another(&m, 2);
// But only `doit` can be used in method position
m.doit(3); // OK: `m` is automatically borrowed
m.another(4); // ERROR: no method named `another`
}
self
cuando se usa como primer argumento de método, es una abreviatura de self: Self
. También hay &self
, que es equivalente a self: &Self
, y &mut self
, que es equivalente a self: &mut Self
.
Self
en los argumentos del método es azúcar sintáctica para el tipo de recepción del método (es decir, el tipo en el que se encuentra este método). Esto también permite tipos genéricos sin demasiada repetición.