deref <t> trait用于自定义解除引用运算符(*)的行为。
如果实现deref <t>特征,则可以将智能指针视为参考。 因此,在引用上工作的代码也可以用在智能指针上。
常规引用是一种指向某个值的指针,该值存储在其他地方。下面来看一个简单的例子来创建i32类型值的引用,然后使用引用运算符和this引用。
fn main()
{
let a = 20;
let b = &a;
if a==*b
{
println!("a and *b are equal");
}
else
{
println!("they are not equal");
}
}
执行上面示例代码,得到以下结果 -
a and *b are equal
在上面的例子中,a保存i32类型值20,而b包含a变量的引用。 如果使用* b,那么它代表值20。因此,可以比较变量a和* b,它将返回真值。 如果使用&b而不是* b,则编译器会抛出错误“无法将{integer}与{&integer}进行比较”。
box <t>作为引用box <t>指针可用作引用。
下面来看一个简单的例子:
fn main()
{
let a = 11;
let b = box::new(a);
print!("value of *b is {}",*b);
}
输出结果如下所示 -
value of *b is 11
在上面的示例中,box <t>的行为与常规引用类似。 它们之间的唯一区别是b包含指向数据的框,而不是通过使用&运算符引用该值。
现在,创建类似于box <t>类型的智能指针,它们的行为与常规引用有一些不同。
box <t>可以定义为具有一个元素的元组结构,例如mybox <t>。
创建元组结构后,在mybox <t>类型上定义函数。
下面来看一个简单的例子:
struct mybox<t>(t);
impl<t> mybox<t>
{
fn example(y : t)->mybox<t>
{
mybox(y)
}
}
fn main()
{
let a = 8;
let b = mybox::example(a);
print!("value of *b is {}",*b);
}
执行上面示例代码,得到以下结果 -
在上面的例子中,创建了智能指针b,但它不能被解除引用。 因此得出结论,无法取消类似于box <t>类型的自定义指针的引用。
deref trait在标准库中定义,该库用于实现名为deref的方法。deref方法借用self并返回对内部数据的引用。下面来看一个简单的例子:
struct mybox<t>
{
a : t,
}
use :: std::ops::deref;
impl<t> deref for mybox<t>
{
type target = t;
fn deref(&self) ->&t
{
&self.a
}
}
fn main()
{
let b = mybox{a : 10};
print!("{}",*(b.deref()));
}
执行上面示例代码,得到以下结果 -
10
程序说明
deref trait在mybox类型上实现。deref trait实现deref()方法,deref()方法返回a变量的引用。type target = t; 是deref trait的关联类型。关联类型用于声明泛型类型参数。mybox类型的实例 - b 。mybox类型的实例b.deref()调用deref()方法,然后取消引用从deref()方法返回的引用。deref强制是将实现deref trait的引用转换为deref可以将原始类型转换为的引用的过程。deref强制是对函数和方法的参数执行的。deref强制自动发生。下面来看一个简单的例子:
struct mybox<t>(t);
use :: std::ops::deref;
impl<t> mybox<t>
{
fn hello(x:t)->mybox<t>
{
mybox(x)
}
}
impl<t> deref for mybox<t>
{
type target = t;
fn deref(&self) ->&t
{
&self.0
}
}
fn print(m : &i32)
{
print!("{}",m);
}
fn main()
{
let b = mybox::hello(5);
print(&b);
}
执行上面示例代码,得到以下结果 -
5
在上面的例子中,使用参数&b调用print(&b)函数,它是&box <i32>的引用。 在这种情况下,实现deref trait,通过deref强制过程将&box <i32>转换为&i32。
到目前为止,使用deref trait覆盖不可变引用上的*运算符,可以使用derefmut trait覆盖可变引用上的*运算符。
rust在以下三种情况下执行deref强制:
deref <target = u>其中t和u是不可变引用时,则&t转换为&u类型。derefmut <target = u>,其中t和u是可变引用时,则&mut t被转换为&mut u。deref <target = u>,其中t是可变引用而u是不可变引用,则&mut t被转换为&u。