我有一个特点 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)
编译 - 耶!
但是,当我想要一个函数返回foo时bar- 类似于:
impl Bar {
fn get_foo(&self) -> Foo {
self.foo
}
}
Run Code Online (Sandbox Code Playgroud)
显然bar.foo是一个Box<Foo>,所以我得到了error: reference …
我正在使用一个复杂的密钥,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提供了Borrow该HashMap::get方法使用的特征.我理解如何Borrow为简单的键工作.例如,Rust标准库的PathBuf实现Borrow<Path> …
是否可以使用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) 我想删除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) 我有一个HashMap<(String, usize), f64>.我也有一个&str和一个usize,我想在HashMap没有克隆的情况下查看.有没有一种方法来查找一(&str, usize)为(String, usize)不知何故?
为什么代码示例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) 我想创建一对新类型Tag(str)and TagBuf(String),类似于 howPath和PathBufwrap 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) 我正在努力解决对象安全的基础问题.如果我有这个代码
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) …