rust 属性可以选择取消引用一个复制对象的引用?

u1ehiz5o  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(113)

我正在实现一个函数,它通过值获取一个元素列表,但是我需要对列表执行两次遍历。第一次遍历计算输入数据的值(不修改输入数据),第二次遍历消耗输入数据。
基本上,类似这样的东西:

fn make_from_elements<K, V, C>(elements: C) -> Container<K, V>
where
    K: Copy + Ord,
    C: IntoIterator<Item = (K, V)>,
    for<'a> &'a C: IntoIterator<Item = (&'a K, &'a V)>,
{
    let max_key = (&elements).into_iter().map(|(k, v)| *k).max().unwrap();
    make_container(max_key, elements)
}

字符串
然而,上面的代码假设(&elements).into_iter().map(|(k, v)| k)是一个iterator,它的项类型是&K。对于我拥有的一些特殊容器,这并不总是正确的;有时,上面的表达式是一个iterator,它的项类型是K(没有引用)。是否有一个trait Package 了实现Copy的可能引用的对象?
换句话说,我试图找到一些应该像这样工作的东西:

fn make_from_elements<K, V, C, Q>(elements: C) -> Container<K, V>
where
    K: Copy + Ord,
    C: IntoIterator<Item = (K, V)>,
    for<'a> &'a C: IntoIterator<Item = (Q + 'a, &'a V)>,
    Q: MaybeDerefCopy<K>,
{
    let max_key = (&elements).into_iter().map(|(k, v)| k.maybe_deref_copy()).max().unwrap();
    make_container(max_key, elements)
}


我怎么能在Rust中做这样的事情呢?

cetgtptt

cetgtptt1#

Borrow trait应该在这里工作,因为T&T都实现了Borrow<T>

fn make_from_elements<KR, K, V, C>(elements: C) -> Container<K, V>
where
    K: Copy + Ord,
    KR: Borrow<K>,
    C: IntoIterator<Item = (KR, V)>,
    for<'a> &'a C: IntoIterator<Item = (&'a KR, &'a V)>,
{
    let max_key = (&elements).into_iter().map(|(k, v)| *k.borrow()).max().unwrap();
    make_container(max_key, elements)
}

字符串
你也可以通过要求Clone而不是Copy来使你的函数支持更多的类型。Copy类型的Clone实现应该已经委托给一个简单的按位复制,无论如何都应该内联,所以对于Copy类型的性能将不受影响。

fn make_from_elements<KR, K, V, C>(elements: C) -> Container<K, V>
where
    K: Clone + Ord,
    KR: Borrow<K>,
    C: IntoIterator<Item = (KR, V)>,
    for<'a> &'a C: IntoIterator<Item = (&'a KR, &'a V)>,
{
    let max_key = (&elements)
        .into_iter()
        .map(|(k, v)| k.borrow().clone())
        .max()
        .unwrap();
    make_container(max_key, elements)
}

相关问题