Rust中对Box
对象的方法调用会自动取消引用Box
Package 器中包含的对象。
举个例子
let my_variable: std::boxed::Box<i32> = std::boxed::Box::new(42);
let my_new_variable = my_variable.ilog2();
这个例子是人为的。这里的重要概念是,函数(在本例中为ilog2
)可以在 Package 在盒子中的某个类型(在本例中为i32
)上调用。
在C++中,解引用和函数调用操作符是必需的:
// C++ would require this
my_new_variable = my_variable->ilog2();
我的问题如下:
- “装箱”对象的自动解引用是否会阻止在
Box
类型本身上调用函数?这样的函数调用是否被隐式地 * 禁止 *?
进一步阐述:
类型Box
包含一个名为leak
的函数。
- 如果方法调用隐式地取消引用Box的内容,那么如何在Box对象上调用函数
leak()
? - 如果调用一个与Box对象相关的函数,在一个Box对象上,“只是工作”,那么如何消除两个同名函数调用之间的歧义?(一个与
Box
关联,一个与Box
中包含的类型关联)
语法上:
如果Box
Package 了类型T
,使得我们有Box<T>
,Box
有一个函数Box::leak()
,T
有一个函数T::leak()
,我们如何消除这两个函数调用之间的歧义?
2条答案
按热度按时间6qftjkof1#
这方面的细节可以在Method call expressions上的参考中找到。其要点如下
例如,如果接收器具有类型Box〈[i32;2]〉,则候选类型将是Box〈[i32;2]〉,&Box〈[i32;2]〉,&mut Box〈[i32;2]〉,[i32; 2](通过解引用),&[i32;2],&mut [i32;2],[i32](通过无大小强制),&[i32],最后&mut [i32]。
也就是说,如果
Box<T>
有一个方法.quack()
,而T
有一个同名的方法,则像foo.quack()
这样的方法调用(其中foo
的类型为Box<T>
)将引用Box::quack()
的实现;T::quack()
被有效地遮蔽。至于你的问题,这并不会阻止Box
类型(或任何其他Deref
类型)实现其内部类型也实现的方法,反之亦然。例如:
几乎在所有情况下,这种行为都为调用 Package 在智能指针中的任何
T
上的方法带来了方便。为了在视觉上/心理上消除对T
和智能指针本身没有方法,但智能指针本身通常没有方法,只有关联的函数。Box::leak()
是一个例子,还有许多其他例子,它们强制使用像Box::leak(foo);
这样的语法,而不是foo.leak();
来实现 visual 消除歧义。一个存在视觉/心理歧义的例子是
Rc
/Arc
上的Clone
实现,其中调用foo.clone()
* 看起来像 * 克隆内部T
,而实际上,只是克隆(增加引用计数)外部Rc
/Arc
。q8l4jmvw2#
除了使用方法语法之外,你还可以使用完全限定名,所以即使
Foo::quack
隐藏了Bar::quack
,你仍然可以使用它,定义为this other answer: