相关疑难解决方法(0)

结构中的特征参考

我有一个特点 Foo

pub trait Foo {
   fn do_something(&self) -> f64;
}
Run Code Online (Sandbox Code Playgroud)

以及引用该特征的结构

pub struct Bar {
   foo: Foo,
}
Run Code Online (Sandbox Code Playgroud)

我试着编译

error: reference to trait `Foo` where a type is expected; try `Box<Foo>` or `&Foo`
Run Code Online (Sandbox Code Playgroud)

将结构更改为

struct Bar {
   foo: &Foo,
}
Run Code Online (Sandbox Code Playgroud)

告诉我 error: missing lifetime specifier

将定义更改为

struct Bar {
   foo: Box<Foo>,
}
Run Code Online (Sandbox Code Playgroud)

编译 - 耶!

但是,当我想要一个函数返回foobar- 类似于:

impl Bar {
    fn get_foo(&self) -> Foo {
        self.foo
    }
}
Run Code Online (Sandbox Code Playgroud)

显然bar.foo是一个Box<Foo>,所以我得到了error: reference …

traits rust

57
推荐指数
3
解决办法
1万
查看次数

什么使某事成为"特质对象"?

最近的Rust改变使得"特质对象"对我来说更加突出,但我只是模糊地掌握了什么让某些东西成为特质对象.特别是一个变化是允许特征对象将特征实现转发到内部类型的即将发生的变化.

鉴于一个特点Foo,我很确定这Box<Foo>是一个特质对象.是否&Foo也是一个特质对象?那么其他智能指针之类的东西Rc还是Arc?我怎样才能创建自己的类型作为特征对象呢?

引用只提到一次trait对象,但没有提到定义.

traits rust

38
推荐指数
3
解决办法
5858
查看次数

如何在为HashMap使用复杂键时避免临时分配?

我正在使用一个复杂的密钥,HashMap使得密钥包含两个部分,一个部分是a String,我无法弄清楚如何通过该HashMap::get方法进行查找而不String为每个查找分配新的.

这是一些代码:

#[derive(Debug, Eq, Hash, PartialEq)]
struct Complex {
    n: i32,
    s: String,
}

impl Complex {
    fn new<S: Into<String>>(n: i32, s: S) -> Self {
        Complex { n: n, s: s.into() }
    }
}

fn main() {
    let mut m = std::collections::HashMap::<Complex, i32>::new();
    m.insert(Complex::new(42, "foo"), 123);

    // OK, but allocates temporary String
    assert_eq!(123, *m.get(&Complex::new(42, "foo")).unwrap());
}
Run Code Online (Sandbox Code Playgroud)

问题出在最后的断言上.它通过,但它需要临时堆分配,因为我不能构造一个Complex没有构造一个String.

为了消除这样的临时分配,Rust提供了BorrowHashMap::get方法使用的特征.我理解如何Borrow为简单的键工作.例如,Rust标准库的PathBuf实现Borrow<Path> …

rust

13
推荐指数
2
解决办法
907
查看次数

如何使用仅在条目空缺时构建的昂贵密钥使用Entry API?

是否可以使用EntryAPI通过a获取值AsRef<str>,但是将其插入Into<String>

这是工作示例:

use std::collections::hash_map::{Entry, HashMap};

struct Foo;

#[derive(Default)]
struct Map {
    map: HashMap<String, Foo>,
}

impl Map {
    fn get(&self, key: impl AsRef<str>) -> &Foo {
        self.map.get(key.as_ref()).unwrap()
    }

    fn create(&mut self, key: impl Into<String>) -> &mut Foo {
        match self.map.entry(key.into()) {
            Entry::Vacant(entry) => entry.insert(Foo {}),
            _ => panic!(),
        }
    }

    fn get_or_create(&mut self, key: impl Into<String>) -> &mut Foo {
        match self.map.entry(key.into()) {
            Entry::Vacant(entry) => entry.insert(Foo {}),
            Entry::Occupied(entry) => entry.into_mut(),
        }
    }
}

fn …
Run Code Online (Sandbox Code Playgroud)

hashmap rust

8
推荐指数
2
解决办法
239
查看次数

通过迭代从BTreeMap或BTreeSet中删除项目

我想删除BTreeMap通过迭代找到的项目.

由于在迭代时无法删除项目,因此我将要删除的项目放入向量中.主要问题是不可能使用引用向量,而只能使用值向量.必须克隆必须删除条目的所有密钥(假设密钥实现了Clone特征).

例如,这个简短的示例不编译:

use std::collections::BTreeMap;

pub fn clean() {
    let mut map = BTreeMap::<String, i32>::new();

    let mut to_delete = Vec::new();

    {
        for (k, v) in map.iter() {
            if *v > 10 {
                to_delete.push(k);
            }
        }
    }

    for k in to_delete.drain(..) {
        map.remove(k);
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

它在编译时会产生以下错误:

error[E0502]: cannot borrow `map` as mutable because it is also borrowed as immutable
  --> src/main.rs:17:9
   |
9  |         for (k, v) in map.iter() {
   |                       --- …
Run Code Online (Sandbox Code Playgroud)

rust

6
推荐指数
1
解决办法
1343
查看次数

在Rust中查找HashMap <(String,usize),f64>中的键

我有一个HashMap<(String, usize), f64>.我也有一个&str和一个usize,我想在HashMap没有克隆的情况下查看.有没有一种方法来查找一(&str, usize)(String, usize)不知何故?

rust

5
推荐指数
1
解决办法
352
查看次数

为什么一致性规则会引发错误"类型参数必须用作某些本地类型的类型参数"?

为什么代码示例1编译但示例2给出了编译错误?

例1:

use std::ops::Index;

struct Bounded {
    idx: usize,
}

impl Index<Bounded> for [i32; 4] {
    type Output = i32;

    fn index(&self, b: Bounded) -> &i32 {
        unsafe { self.get_unchecked(b.idx) }
    }
}
Run Code Online (Sandbox Code Playgroud)

例2:

use std::ops::Index;

struct Bounded {
    idx: usize,
}

impl<T> Index<Bounded> for [T; 4] {
    type Output = T;

    fn index(&self, b: Bounded) -> &T {
        unsafe { self.get_unchecked(b.idx) }
    }
}
Run Code Online (Sandbox Code Playgroud)
error[E0210]: type parameter `T` must be used as the type parameter for some local type …
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
381
查看次数

如何在安全的 Rust 中为未调整大小的类型及其拥有的对应物(如 `str` 和 `String`)创建新类型?

我想创建一对新类型Tag(str)and TagBuf(String),类似于 howPathPathBufwrap OsStrand OsString。我的最终目标是拥有一个TagBuf以 为键的地图,并且能够只用一个索引来索引它Tag

fn main() {
    let mut m: HashMap<TagBuf, i32> = HashMap::new();
    m.insert(TagBuf("x".to_string()), 1);
    assert_eq!(m.get(Tag::new("x")), Some(&1));
}
Run Code Online (Sandbox Code Playgroud)

但是我遇到了问题,因为它Tag是动态大小的。

具体来说,实施起来Borrow<Tag> for TagBuf很棘手:

pub struct Tag(str);
pub struct TagBuf(String);

impl std::borrow::Borrow<Tag> for TagBuf {
    fn borrow(&self) -> &Tag {
        let s: &str = self.0.as_str();
        // How can I turn `&str` into `&Tag`? A naive attempt fails:
        &Tag(*s)
    }
}
Run Code Online (Sandbox Code Playgroud)
error[E0277]: …
Run Code Online (Sandbox Code Playgroud)

rust newtype

5
推荐指数
1
解决办法
224
查看次数

了解特征和对象安全

我正在努力解决对象安全的基础问题.如果我有这个代码

struct S {
    x: i32
}

trait Trait: Sized {
    fn f(&self) -> i32 where Self: Sized;
}

fn object_safety_dynamic(x: Trait) {}
Run Code Online (Sandbox Code Playgroud)

我收到

fn object_safety_dynamic(x: Trait) {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `traits::Trait` cannot be made into an object
= note: the trait cannot require that `Self : Sized`
Run Code Online (Sandbox Code Playgroud)

当添加/更改:Sized为特征的继承或f绑定时,我收到稍微不同的错误消息.

有人能解释一下:

  • 为什么这个特定的例子不起作用?Trait Objects一章说明"那么什么使方法对象安全?每种方法都必须要求Self: Sized".那不是满满的吗?

  • Trait: Sized和之间有什么区别where Self: Sized?(嗯,是的,一个继承了特性,另一个是参数绑定,但是从Rust的特质对象的角度来看?

  • 我必须做的首选改变是什么object_safety_dynamic

rustc 1.19.0-nightly (01951a61a 2017-05-20) …

traits rust trait-objects

3
推荐指数
2
解决办法
1279
查看次数

标签 统计

rust ×9

traits ×3

hashmap ×1

newtype ×1

trait-objects ×1