首页 > 解决方案 > 接受必须是引用的泛型类型的函数的惯用类型签名是什么?

问题描述

#[allow(dead_code)]
fn contains<'a, V, T, Q>(arr: V, value: &Q) -> bool
where
    T: 'a + std::cmp::PartialEq<Q>,
    V: std::iter::IntoIterator<Item = &'a T>,
{
    arr.into_iter().any(|v| v == value)
}

#[test]
fn test_contains_hash_set() {
    use std::collections::HashSet;

    let hs_str: HashSet<&str> = ["a", "b", "c"].iter().copied().collect();
    let hs_string: HashSet<String> = vec!["a".to_string(), "b".to_string(), "c".to_string()]
        .into_iter()
        .collect();

    let value_str = "b";
    let value_string = String::from(value_str);

    assert!(contains(&hs_str, &value_string));
    assert!(contains(&hs_string, &value_str));
    assert!(contains(&hs_string, &"a"));
}

#[test]
fn test_contains_vec() {
    let array_str = ["a", "b", "c"];
    let array_string = ["a".to_string(), "b".to_string(), "c".to_string()];

    let value_str = "b";
    let value_string = String::from(value_str);

    assert!(contains(&array_str, &value_string));
    assert!(contains(&array_string, &value_str));
    assert!(contains(&array_string, &"b"));

    //assert!(contains(array_string, &"b"));
    // ^^^ testing the compiler error for when there is no &
}

游乐场

忽略该声明,我可以阅读aswhere的类型签名。我会假设,不管是什么,它都是一种将被移动的具体类型。containscontains(V, &Q) -> boolV

包括where语句,V成为对可以变成&Ts 的迭代器的东西的引用。根据我之前的假设,我想V变成&V; 但是它不会编译,因为它成为对某物的引用的引用。

如果另一个开发人员不知道std::iter::IntoIterator<Item = &'a T>是如何实现的,他们会认为V是移动的具体类型吗?有什么方法可以在V期望引用的类型签名中显示?

正如trentcl 在评论中解释的那样

V不期待参考。V恰好您使用它的所有地方的参考,但不一定是。

正如函数contains类型签名所代表的那样,它可以以更惯用的方式编写吗?

标签: genericstypesrust

解决方案


推荐阅读