rust - Rust 编译器在多大程度上自动匹配泛型约束?

标签 rust

考虑以下二叉树代码

#[derive(Debug)]
struct Binary_Tree_Node<T: PartialOrd + Clone> {
    left: Binary_Tree<T>,
    value: T,
    right: Binary_Tree<T>
}

#[derive(Debug)]
struct Binary_Tree<T: PartialOrd + Clone> {
    node: Option<Box<Binary_Tree_Node<T>>> 
}

impl <T: PartialOrd + Clone>Binary_Tree<T> {
    fn new(value_to_insert: T) -> Binary_Tree<T> {
        Binary_Tree{node: 
            Some(
                Box::new(
                    Binary_Tree_Node{
                        left: Binary_Tree{node: None}, 
                        value: value_to_insert, 
                        right: Binary_Tree{node: None}
                    }
                )
            )
        }
    }

    fn map<F, U>(&self, f: F) -> Option<U> 
    where F: FnOnce(&Binary_Tree_Node<T>) -> U {
        self.node.as_ref().map(|node| f(&**node))
        // equivalent 
        //self.node.as_ref().map(|node| f(node))
    }
}
let mut test1 = Binary_Tree::new(10);
println!("{:#?}", test1.map(|node| node.value < 2));

这条线让我很困惑

self.node.as_ref().map(|node| f(node))

因为我预计 rust 会抛出编译器错误

self.node类型为 Option<Box<Binary_Tree_Node<T>>>

self.node.as_ref()类型为 Option<&Box<Binary_Tree_Node<T>>>

nodeself.node.as_ref().map(|node| f(node))类型为 &Box<Binary_Tree_Node<T>>

&Box<Binary_Tree_Node<T>>不等同于通用约束 &Binary_Tree_Node<T>

问题是为什么self.node.as_ref().map(|node| f(&**node))self.node.as_ref().map(|node| f(node))工作?

最佳答案

这是一个“Deref 强制转换”,参见 nomicon Coercions :

Coercion is allowed between the following types:

  • [...]
  • Deref coercion: Expression &x of type &T to &*x of type &U if T derefs to U (i.e. T: Deref<Target=U>)

Box<T>工具 Deref<Target=T> , 所以 &Box<T>自动强制转换为 &T就像你写的一样 &*node .

(我不确定“表达式 &”部分中的 &x 是做什么用的,因为我们在强制站点上没有 & 但它仍然有效 - 可能是拼写错误或错误)

也适用于 &String&str : Playground

fn foo<T>(_v: T) {}

fn main() {
    {
        let v: &Box<i32> = &Box::new(5i32);
        foo::<&i32>(v);
        foo::<&i32>(&*v);
    }

    {
        let v: &String = &String::from("abc");
        foo::<&str>(v);
        foo::<&str>(&*v);
    }
}

关于rust - Rust 编译器在多大程度上自动匹配泛型约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47547978/

相关文章:

c - 链接 C/Rust "Hello world"时出错:未定义对 `std::io::stdio::_print 的引用

gcc - 创建和链接静态 rust 库并链接到 c

rust - 是否有指定数字功能的任何特征?

data-structures - 重组结构内的盒装元素

rust - 我如何使用带有非静态字符串的彩色 crate ?

arrays - 如何使用泛型和特征从数组中获取最大的元素?

rust - 在不复制操作数的情况下重载 Add-operator

json - 从 Rust 中的 Json 枚举中读取特定字段

rust - Pin::as_mut(&mut self )

rust - 如何强制联合表现得好像只有一种类型?