2014-07-24 18 views
7

Próbuję napisać funkcję drukowania dla binarnego drzewa i tutaj jest to, co mam tak daleko:Jak używać przeciążania parametrów lub opcjonalnych parametrów w rdzeniu?

impl TreeNode { 
    fn print(&self) { 
     self.print(0); 
    } 
    fn print(&self, level: u8) { 
     for _i in range(0,level) { 
      print!("\t"); 
     } 
     match self.data { 
      Some(x) => println!("{}",x), 
      None =>() 
     }; 
     match self.left { 
      Some(ref x) => x.print(level+1), 
      None =>() 
     }; 
     match self.right { 
      Some(ref x) => x.print(level+1), 
      None =>() 
     }; 
    } 
} 

otrzymuję błąd: powielać definicję wartości print. Tak więc zastanawiałem się, czy istnieje sposób na tworzenie funkcji o tej samej nazwie, ale różnych argumentów. Ewentualnie opcjonalne parametry rozwiązałyby ten problem, ale nie sądzę, że jest to możliwe w tej chwili (przynajmniej nie mogłem go znaleźć za pomocą wyszukiwarki Google).

Jaki jest najlepszy sposób na zrobienie tego? Zmiana nazwy drugiej funkcji drukowania działa, ale wygląda brzydko i wymaga zapamiętania więcej niż jednej nazwy funkcji, jeśli chcę (na potrzeby tego przykładu) drukować zaczynając od środka drzewa.

Odpowiedz

4

Rust nie ma przeciążenia, więc niemożliwe jest posiadanie dwóch funkcji lub metod o tej samej nazwie iz różnymi zestawami parametrów.

Jednak czasami można emulować przeciążenie za pomocą cech. Takie podejście jest prawdopodobnie nieodpowiednie dla przypadku użycia, ale można zobaczyć, jak to się robi in the standard library, gdzie Path::new() konstruktor można nazwać czymś przypominającym wektor bajtów:

Path::new("https://stackoverflow.com/a/b/c/d") // argument is &str 
Path::new(b"https://stackoverflow.com/a/b/c/d") // argument is &[u8] 
Path::new(Path::new("https://stackoverflow.com/a/b/c/d")) // argument is another Path 

Odbywa się to poprzez BytesContainer cechy i new() metoda jest zdefiniowana następująco:

fn new<T: BytesContainer>(bytes: T) -> Path { ... } 

Wtedy ta cecha jest realizowany dla wszystkich typów ma:

impl<'a> BytesContainer for &'a str { ... } 
impl<'a> BytesContainer for &'a [u8] { ... } 
impl BytesContainer for Path { ... } 
// and more 

Przypomina to przeciążenie właśnie dlatego, że new() robi dokładnie to samo, bez względu na to, jakiego rodzaju dane wejściowe jest dostarczane; jest to po prostu wygoda, która sprawia, że ​​konstruktor Path jest bardziej elastyczny. W końcu new() po prostu konwertuje swój argument do bajta. Nie pozwala to jednak na posiadanie zupełnie różnych funkcji o tej samej nazwie.

+2

To sprawia, że ​​jestem smutny. A zatem, wracając do mojego przykładu, najlepiej byłoby wymienić drugą funkcję na "print_at_level" i po prostu to zostawić? – user439299

+1

@ user439299, tak, dokładnie. –

Powiązane problemy