我的问题在这里很具体。我想禁用隐式deref强制(可以说是因为我不喜欢它们)。更具体地说,我希望此代码失败:
fn main() {
let x = Box::new(0);
let mut y = &x;
y = &mut y;
println!("GOT {}",*y);
}
在我看来,这是一个很荒谬的例子。但是,它之所以编译是因为(我认为)
&mut T
强制转换为T
,因此y = &mut y
语句是nop。假设这是正确的,如何防止Rust这样做呢?例如,我尝试使用
#[no_implicit_prelude]
,但没有任何乐趣。
最佳答案
您提供的代码实际上并未使用任何自动引用。 y
的类型是&Box<i32>
,而println
可以工作,因为Display
的Box
格式仅是委派给其内容Display
实现。
如果我稍微更改您的示例,我们可以发挥自动取消引用的作用:
fn main() {
let x = Box::new(0);
let mut y: &i32 = &x; // <-- Deref impl is used here
y = &mut y;
println!("GOT {}", y);
}
您不能禁用为内置类型实现的任何特征。您可以创建自己的不实现
Box
的Deref
:use std::{boxed, fmt};
struct Box<T>(boxed::Box<T>);
impl<T> Box<T> {
pub fn new(value: T) -> Self {
Self(boxed::Box::new(value))
}
}
impl<T: fmt::Display> fmt::Display for Box<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
自动取消引用不起作用:
fn main() {
let x = Box::new(0);
let mut y: &i32 = &x; // <-- Error: expected `i32`, found struct `Box`
y = &mut y;
println!("GOT {}", y);
}
但是您仍然可以打印包装盒本身:
fn main() {
let x = Box::new(0);
let mut y = &x;
y = &mut y;
println!("GOT {}", y); // y: &Box<i32>
}
我不确定为什么您会这么做。您将不得不重新实现的
Box
功能的很多才能使其普遍有用,并且完全不清楚没有Deref
impl有什么好处。
关于rust - 禁用隐式Deref强制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61264079/