Rust中引用传递与Deref实现疑问:类型输出为何不符合预期?
问题解答
一、类型打印异常的原因
你的print_type_of函数大概率是通过Deref::Target获取类型,而非直接打印输入参数本身的类型。举个完全匹配你描述的实现例子:
use std::ops::Deref; fn print_type_of<T: Deref>(t: T) { println!("{}", std::any::type_name::<T::Target>()); } fn print_type_of_without_ampersand<T>(t: T) { println!("{}", std::any::type_name::<T>()); }
- 调用
print_type_of(&1)时,T被推导为&i32,T::Target对应i32,所以输出i32; - 调用
print_type_of(&&1)时,T被推导为&&i32,T::Target对应&i32,所以输出&i32; - 而
print_type_of_without_ampersand(&1)直接打印参数本身的类型&i32,完全符合你的预期。
如果你的print_type_of是参数为&T的写法:
fn print_type_of<T>(_: &T) { println!("{}", std::any::type_name::<T>()); }
调用print_type_of(&1)时,输入的&i32匹配&T,T被推导为i32,输出i32;调用print_type_of(&&1)时,Rust会触发自动解引用(Deref Coercion),把&&i32转换成&i32匹配参数,此时T仍是i32——但这和你描述的输出&i32不符,所以更可能是第一种基于Deref::Target的实现。
二、&T的Deref实现逻辑
Rust标准库中对&T的Deref实现如下:
impl<T> Deref for &T { type Target = T; fn deref(&self) -> &T { *self } }
你觉得矛盾的核心是混淆了Self(当前实现Deref的类型)和Target(解引用后的目标类型)的层级关系:
- 当
Self是&i32时,T=i32,Target=i32,deref返回&i32(指向目标类型的引用),对&i32用*运算符就会得到i32; - 当
Self是&&i32时,本质是&T且T=&i32,所以Target=&i32,deref返回&&i32(指向目标类型的引用),对&&i32用*运算符会先调用deref得到&i32,再解引用一次就能得到i32——整个逻辑完全自洽,嵌套引用的解引用就是逐层剥离的过程。
内容的提问来源于stack exchange,提问作者Lorenzo Yang
相关产品推荐
相关产品推荐

