在不使用克隆特征的情况下从集合中获取价值 [英] Getting value from a collection without using the Clone trait

查看:132
本文介绍了在不使用克隆特征的情况下从集合中获取价值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以从集合中获取值并对其应用仅接受self而不接受&self的方法?

Is it possible to get a value from a collection and apply a method to it which accepts only self and not &self?

最小工作示例

我想写的东西类似于:

use std::collections::HashMap;

fn get<B>(key: i32, h: HashMap<i32, Vec<(i32, B)>>) -> i32 where B: Into<i32> {
    let v: &Vec<(i32, B)> = h.get(&key).unwrap();
    let val: &B = v.first().unwrap().1;

    // Do something to be able to call into
    // I only need the value as read-only
    // Does B have to implement the Clone trait?
    return val.into();
}

我曾在这里和那里徒劳地运球mut,试图在编译器错误后安抚编译器错误,但这确实是傻瓜的事.

I have tried in vain to dribble mut here and there to try to appease compiler error after compiler error, but this is really a fool's errand.

use std::collections::HashMap;

fn get<B>(key: i32, mut h: HashMap<i32, Vec<(i32, B)>>) -> i32 where B: Into<i32> {
    let mut v: &Vec<(i32, B)> = h.get_mut(&key).unwrap();
    let ref mut val: B = v.first_mut().unwrap().1;
    return (*val).into();
}

这种事情是否可能实现?或者B是否必须实现Clone特征?

Is this sort of thing even possible or does B have to implement the Clone trait?

我也尝试过:

  • 不安全
  • 原始指针

我没有尝试过:

  • Box
  • 我还没有遇到过的其他Rust构造, 我提到这一点是为了明确指出我还没有 省略了我所知道的任何方法.
  • Box
  • Other Rust constructs that I have not encountered, I mention this to explicitly state that I have not omitted any approaches that I know of.

推荐答案

是否可以从集合中获取值并对其应用仅接受self而不接受&self的方法?

Is it possible to get a value from a collection and apply a method to it which accepts only self and not &self?

通常,不,并非没有将其从集合中删除.集合拥有价值.采用self的方法要在消耗所有权的同时转换项目,因此您必须转让所有权.

In general, no, not without removing it from the collection. The collection owns the value. Methods that take self want to transform the item while consuming the ownership, so you have to transfer ownership.

克隆或复制项目会创建一个具有新所有权的新项目,然后您可以将其赋予该方法.

Cloning or copying an item creates a new item with new ownership that you can then give to the method.

在您的特定情况下,您可以几乎摆脱这个令人兴奋的where子句:

In your particular case, you can almost get away with this exciting where clause:

where for<'a> &'a B: Into<i32>

除了i32之外,没有为i32实现.您可以编写一个可以满足您需求的特征:

Except From<&i32> is not implemented for i32. You can write a trait that does what you want though:

use std::collections::HashMap;

trait RefInto<T> {
    fn into(&self) -> T;
}

impl RefInto<i32> for i32 {
    fn into(&self) -> i32 { *self }
}

fn get<B>(key: i32, h: HashMap<i32, Vec<(i32, B)>>) -> i32
    where B: RefInto<i32>
{
    let v = h.get(&key).unwrap();
    let val = &v.first().unwrap().1;

    val.into()
}

// ----

fn main() {
    let mut map = HashMap::new();
    map.insert(42, vec![(100, 200)]);
    let v = get(42, map);
    println!("{:?}", v);
}

或者,您也许可以使用 Borrow :

Alternatively, you might be able to make use of Borrow:

use std::collections::HashMap;
use std::borrow::Borrow;

fn get<B>(key: i32, h: HashMap<i32, Vec<(i32, B)>>) -> i32
    where B: Borrow<i32>
{
    let v = h.get(&key).unwrap();
    let val = &v.first().unwrap().1;

    *val.borrow()
}

这篇关于在不使用克隆特征的情况下从集合中获取价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆