Czy program formatujący debugowania używa wyłuskiwania?
Nie wiem, w jaki sposób program formatujący debugowanie trafia na koniec łańcucha referencyjnego.
Rozumiem, że println!("{:?}", x)rozszerza się to do czegoś takiego:
... print(&x) ...
który pożycza xzamiast przenosić / kopiować.
Teraz drukuje MyNumber(1)zamiast oczekiwanego &MyNumber(1):
#[derive(Debug)]
struct MyNumber(u8);
fn main() {
let x = MyNumber(1);
println!("{:?}", x);
}
z którego zakładam, że program formatujący Debug jest zgodny z ogólną Derefimplementacją zdefiniowaną dla wszystkich odwołań przez sam język Rust ( impl<T> Deref for &T).
Jeśli tak, to dlaczego następujący kod jest drukowany MyNumber(1)zamiast tylko 1?
use std::ops::{Deref};
#[derive(Debug)]
struct MyNumber(u8);
impl Deref for MyNumber {
type Target = u8;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let x = MyNumber(1);
println!("{:?}", x);
}
Wydaje mi się, że program formatujący Debug jest zgodny z Derefzaimplementowanym &Tprzez sam język Rust, ale ignoruje Derefimplementację na moim niestandardowym typie.
Czy ktoś wie, dlaczego tak się dzieje? Każda pomoc bardzo doceniona!
Odpowiedzi
Czy ktoś wie, dlaczego tak się dzieje? Każda pomoc bardzo doceniona!
Jeśli sprawdzisz dokumentację dotyczącą debugowania, przeszukaj , aby znaleźć :
impl<'_, T> Debug for &'_ T where
T: Debug + ?Sized,
Oznacza to, że istnieje implementacja zbiorcza w szczególności w odniesieniu do odwołań, które są delegowane do bazowego obiektu. W twoim przypadku to jest to MyNumber, co jest używane.
Nie ma implementacji dla Deref, zamiast tego istnieją implementacje dla każdego typu inteligentnego wskaźnika (jeśli przeszukasz stronę, znajdziesz implementacje Boxi Rc).
Więc twój kod jest drukowany, MyNumber(1)ponieważ tak mu nakazano: wywołuje Debugimplementację MyNumber. Jeśli chcesz czegoś innego, musisz zaimplementować (nie wyprowadzać), Debugaby delegować do jego bazowego typu.