匹配:Deref和标记运算符,为什么它们不一样?

时间:2017-02-26 20:24:39

标签: rust

以下是example of usage Deref的修改版本:

use std::ops::Deref;
use std::rc::Rc;

#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
pub struct InternedString {
    string: Rc<String>,
}

impl InternedString {
    #[inline]
    pub fn new(string: &'static str) -> InternedString {
        InternedString {
            string: Rc::new(string.to_owned()),
        }
    }
}

impl Deref for InternedString {
    type Target = str;

    fn deref(&self) -> &str { &self.string }
}


struct DerefExample<T> {
    value: T
}

impl<T> Deref for DerefExample<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.value
    }
}

fn main() {
    let x = DerefExample { value: 'a' };
    assert_eq!('a', *x);

    match *x {
        'a' => (),
        _ => (),
    };

    let s = InternedString::new("aaa");
    match *s {
        "test" => (),
        _ => (),
    };
}

未编译,错误:

55 |         "test" => (),
   |         ^^^^^^ expected str, found reference
   |
   = note: expected type `str`
   = note:    found type `&'static str`

但如果我手动调用deref方法:

match s.deref() {
    "test" => (),
    _ => (),
}

所有编译都没有错误,*ss.deref()之间有什么区别,为什么char一切正常?

1 个答案:

答案 0 :(得分:4)

字符文字的类型为char,而字符串文字的类型为&'static str。请注意,字符串文字始终是引用,而字符文字不是引用。

执行deref强制时,

*s实际上已转换为*(s.deref()),而不是s.deref(),因为deref会返回引用。因此,要将InternedString与字符串文字相匹配,您需要引用*s,即您需要编写&*s而不是*s。这是有效的,因为*s产生左值。