Apakah pemformat Debug menggunakan dereference?
Saya bingung tentang bagaimana pemformat Debug sampai ke akhir rantai referensi.
Pemahaman saya adalah itu println!("{:?}", x)berkembang menjadi sesuatu seperti:
... print(&x) ...
yang meminjam xalih-alih memindahkan / menyalinnya.
Sekarang ini mencetak MyNumber(1)alih-alih yang diharapkan &MyNumber(1):
#[derive(Debug)]
struct MyNumber(u8);
fn main() {
let x = MyNumber(1);
println!("{:?}", x);
}
dari mana saya berasumsi bahwa pemformat Debug mengikuti Derefimplementasi umum yang ditentukan untuk semua referensi oleh bahasa Rust itu sendiri ( impl<T> Deref for &T).
Jika demikian, lalu mengapa kode berikut dicetak, MyNumber(1)bukan hanya 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);
}
Tampaknya bagi saya bahwa pemformat Debug mengikuti yang Derefditerapkan &Toleh bahasa Rust itu sendiri tetapi mengabaikan yang Derefditerapkan pada tipe kustom saya.
Apakah ada yang tahu mengapa hal ini terjadi? Setiap bantuan sangat dihargai!
Jawaban
Apakah ada yang tahu mengapa hal ini terjadi? Setiap bantuan sangat dihargai!
Jika Anda memeriksa dokumentasi untuk Debug kemudian mencari di sekitar Anda akan menemukan :
impl<'_, T> Debug for &'_ T where
T: Debug + ?Sized,
Artinya ada implementasi massal khususnya pada referensi yang didelegasikan ke objek yang mendasarinya. Yang mana dalam kasus Anda MyNumber, pada titik mana itulah yang digunakan.
Tidak ada implementasi untuk Deref, sebagai gantinya ada implementasi untuk setiap jenis pointer pintar (jika Anda menelusuri di halaman Anda akan menemukan implementasi untuk Boxdan Rc).
Jadi kode Anda dicetak MyNumber(1)karena itulah yang diperintahkan: kode ini memanggil Debugimplementasi pada MyNumber. Jika Anda menginginkan sesuatu yang berbeda, Anda perlu mengimplementasikan (bukan menurunkan) Debuguntuk mendelegasikan ke jenis dasarnya.