代码之家  ›  专栏  ›  技术社区  ›  NebulaFox

我应该使用哪种类型的declaration来创建我自己的包含

  •  0
  • NebulaFox  · 技术社区  · 6 年前

    我正在努力理解Rust的类型系统。

    use std::collections::HashSet;
    
    fn hs_contains<T>(hs: &HashSet<T>, value: &T) -> bool
    where 
        T: PartialEq,
    {
        hs.iter().any(|v| v == value)
    }
    
    fn main() {
        // move strings into HashSet
        let known_values: HashSet<&str> = ["a", "b", "c"].iter().cloned().collect();
    
        // provided an Vec<String>
        let provided_values: Vec<String> = vec!["a".to_string(), "b".to_string(), "z".to_string()];
    
        // hash set of refrences
        let mut found: HashSet<&str> = HashSet::new();
        found.insert(&provided_values[0]);
        found.insert(&provided_values[1]);
        found.insert(&provided_values[2]);
    
        let missing: HashSet<_> = known_values.difference(&found).collect();
    
        let value: &String = &provided_values[1];
    
        hs_contains(&known_values, value);
        hs_contains(&missing, "c");
    
        println!("missing: {:#?}", missing);
    }
    

    ( Playground )

    示例代码无法编译,因为类型不强制。是否有可能为 hs_contains 这将满足示例底部的条件:

    hs_contains(&known_values, value);
    hs_contains(&missing, "c");
    

    我为什么不直接用 HashSet::contains ?

    更换 hs内容 具有 哈希集::包含

    known_values.contains(value);
    missing.contains(&"c");
    

    导致以下编译错误

    error[E0277]: the trait bound `&str: std::borrow::Borrow<std::string::String>` is not satisfied
      --> src/main.rs:38:18
       |
    38 |     known_values.contains(value);
       |                  ^^^^^^^^ the trait `std::borrow::Borrow<std::string::String>` is not implemented for `&str`
    

    我所知道的唯一其他方法是

    known_values.iter().any(|v| v == value);
    

    这激起了我对如何用类型声明定义一个可以封装上述内容的函数的兴趣。

    0 回复  |  直到 6 年前
        1
  •  0
  •   NebulaFox    6 年前

    一个小的改变可以使它编译:移动 & 从函数的声明到函数体内部

    fn hs_contains<T>(hs: &HashSet<T>, value: T) -> bool
    where
        T: std::cmp::PartialEq,
    {
        hs.iter().any(|v| v == &value)
    }
    

    并添加一个 & 上 "c"

    hs_contains(&missing, &"c" );
    

    ( Playground )


    现在为什么要搬家 & 函数内部有什么不同吗?

    正如Max在下面的评论中所解释的那样

    当你使用 <T> 后来 value:T 你让铁锈弄清楚什么 T 确实如此。在你的情况下,它应该是一个参考 str 当你使用价值 &T 你现在要求提供一个参考 str 一 &&str )

    推荐文章