2015-08-31 18 views

Odpowiedz

22

self używany jako pierwszy argument metody, jest skrótem dla self: Self. Istnieje również &self, który jest równoważny self: &Self i &mut self, co jest równoważne z self: &mut Self.

Self w argumenty metoda jest cukier składniowym dla typu odbiorczego metod (tj rodzaju, który to sposób impl w). Pozwala to również na typy ogólne bez zbytniego powtarzania.

40

Self to typ bieżącego obiektu. Może się wydawać, albo w trait lub impl, ale pojawia się najczęściej w trait gdzie jest to stand-in dla dowolnego typu zakończy się wdrażającego trait (który jest nieznany podczas definiowania trait):

trait Clone { 
    fn clone(&self) -> Self; 
} 

gdybym wtedy wdrożyć 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; 
} 

mogę również używać go w sposób regularny impl jeśli jestem leniwy (to krócej!):

impl MySuperLongType { 
    fn new(a: u32) -> Self { ... } 
} 

self to nazwa w trait lub impl do pierwszego argumentu metody. Korzystanie inna nazwa to możliwe, jednak nie jest zauważalna różnica:

  • przypadku korzystania self funkcja wprowadzona jest metoda
  • w przypadku korzystania z żadnego innego imienia, funkcja wprowadzona jest związana funkcja

W Rust nie ma żadnego niejawnego argumentu przekazanego do metod typu: musisz jawnie przekazać "bieżący obiekt" jako parametr metody. Spowodowałoby:

impl MyType { 
    fn doit(this: &MyType, a: u32) { ... } 
} 

Jak widzieliśmy, jak krótszej formie to może być również (wciąż gadatliwy):

impl MyType { 
    fn doit(this: &Self, a: u32) { ... } 
} 

która jest faktycznie co &self sprowadza się pod kołdrą.

impl MyType { 
    fn doit(&self, a: u32) { ... } 
} 

Zatem tabela korespondencji:

self => self: Self 
&self => self: &Self 
&mut self => self: &mut Self 

Sposób powoływania zmienić te funkcje, jednakże:

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` 
} 
+0

** Może pojawić się w jednej rzeczy lub w impl ** - nie może pojawić się w "struct"? –

+0

@jawanam: Osobiście dostaję * błąd: użycie 'Self' poza impaktem lub cechą *, jeśli spróbuję. Może ograniczenie zostanie zniesione w nowszej wersji? –

+1

Nie, obecnie nie jest możliwe (od rana 2015-09-01). Struktury samo-referencyjne są dość rzadkie, więc dodanie w tym przypadku samoobsługi zostało uznane za niski priorytet. – llogiq

Powiązane problemy