我有收集转储到磁盘上.在请求时,应该检索这些集合(没问题),并且iterator应该为它构建一个返回对检索到的值的引用的集合.
在之后iterator被丢弃,我不需要收集了.我也希望它被删除.
到目前为止我尝试了什么:
在Iterator拥有集合.这对我来说最有意义,但这是不可能的; 我不太清楚为什么.有人说Iterator特征的方法签名next是问题所在.(例子)
引用计数:Retriever返回a Rc<Vec<usize>>.我遇到了与拥有迭代器相同的问题.(例子)
让猎人拥有该集合并分发对它的引用.我尝试使用内部mutability(RefCell<HashMap>)实现检索器,但是我无法将引用返回到HashMap具有足够长的生命周期.
我看到了两个基本的可能性.
检索器转移所有权.然后Iterator需要拥有数据.有些东西:
use std::slice::Iter;
fn retrieve(id: usize) -> Vec<usize> {
//Create Data out of the blue (or disk, or memory, or network. I dont care)
//Move the data out. Transfer ownership
let data = vec![0, 1, 2, 3];
data
}
fn consume_iterator<'a, TIterator: Iterator<Item=&'a usize>>(iterator: TIterator) {
for i …Run Code Online (Sandbox Code Playgroud)是否可以在映射中插入一个结构,其中键由插入的值所拥有?
在C中使用哈希映射时,这是我以前做过的事情.
伪代码示例:
struct MyStruct {
pub map: BTreeMap<&String, StructThatContainsString>,
// XXX ^ Rust wants lifetime specified here!
}
struct StructThatContainsString {
id: String,
other_data: u32,
}
fn my_fn() {
let ms = MyStruct { map: BTreeMap::new() };
let item = StructThatContainsString {
id: "Some Key".to_string(),
other_data: 0,
}
ms.insert(&item.id, item);
}
Run Code Online (Sandbox Code Playgroud)
如何正确处理这种情况?
如果这是不可能的,可以反过来做,其中值持有对密钥的引用,这将是一个String?
另一种方法是使用a set而不是a map,然后将整个存储struct为键,但在比较时只使用其中一个值(似乎它可以工作,但如果你想比较struct其他上下文,可能会适得其反).
我需要定义一个二叉搜索树,其中每个节点都可以访问父节点:
enum Tree<'a> {
Leaf,
Node {
left: Box<Tree<'a>>,
right: Box<Tree<'a>>,
parent: &'a Tree<'a>,
data: u64,
}
}
impl <'a> Tree<'a> {
pub fn new(data: u64, parent: &'a Tree) -> Tree<'a> {
Tree::Node {
left: Box::new(Tree::Leaf),
right: Box::new(Tree::Leaf),
parent,
data
}
}
pub fn insert_at_left_leaf(&'a mut self, data: u64) {
match *self {
Tree::Leaf => panic!("Leaf has no children"),
Tree::Node {ref mut left, ..} => {
**left = Tree::new(data, self);
}
}
}
}
fn main() {
let parent = …Run Code Online (Sandbox Code Playgroud) pub struct ForesterViewModel {
m_tree_lines: Arc<Mutex<Vec<TreeLine>>>,
}
impl ForesterViewModel {
pub fn new() -> ForesterViewModel {
ForesterViewModel {
m_tree_lines: Arc::new(Mutex::new(vec![])),
}
}
pub fn get_the_forest(&mut self) -> &mut Vec<TreeLine> {
???????????????????????????????
}
}
Run Code Online (Sandbox Code Playgroud)
我需要帮助编写该get_the_forest函数。我尝试了很多不同的方法,但它们都返回编译错误。我需要返回一个可变引用,Vec<TreeLine>该引用被包装在self.m_tree_lines.
我正在使用期货,tokio,hyper和serde_json来请求和反序列化我需要保留的一些数据,直到我的下一个请求.我最初的想法是创建一个包含hyper::Chunk从中借用的反序列化数据的结构Chunk,但却无法使生命周期正确.我尝试使用租赁箱,但我也无法使用它.也许我'buffer在宣布缓冲区之前使用了生命周期Vec,但也许我搞砸了别的东西:
#[rental]
pub struct ChunkJson<T: serde::de::Deserialize<'buffer>> {
buffer: Vec<u8>,
json: T
}
Run Code Online (Sandbox Code Playgroud)
有没有办法让生命时间正确,或者我应该使用DeserializeOwned并放弃零拷贝?
有关更多上下文,以下代码可以正常工作(定期从两个URL反序列化JSON,保留结果,以便我们可以对它们执行某些操作).我想改变我的X和Y类型Cow<'a, str>用于他们的领域,从改变DeserializeOwned为Deserialize<'a>.为此,我需要存储已经反序列化的切片,但我不知道如何做到这一点.我正在寻找使用Serde的零拷贝反序列化并保留结果的示例,或者用于重构我的代码的一些想法.
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate futures;
extern crate tokio_core;
extern crate tokio_periodic;
extern crate hyper;
use std::collections::HashMap;
use std::error::Error;
use futures::future;
use futures::Future;
use futures::stream::Stream;
use hyper::Client;
fn stream_json<'a, T: serde::de::DeserializeOwned + Send + 'a>
(handle: …Run Code Online (Sandbox Code Playgroud) 这是我所能得到的,使用rental,部分基于How can I store a Chars iterator in the same struct as the String it iterateing? 。这里的区别在于,get_iter锁定成员的方法必须采用可变的自引用。
我与使用租赁无关:我对使用reffers或owning_ref 的解决方案同样满意。
出现PhantomData在这里只是为了与被迭代的事物MyIter具有正常的生命周期关系。MyIterable
我还尝试更改#[rental]为并更改to#[rental(deref_mut_suffix)]的返回类型,但这给了我源自宏的其他终身错误,我无法破译。MyIterable.get_iterBox<Iterator<Item=i32> + 'a>
#[macro_use]
extern crate rental;
use std::marker::PhantomData;
pub struct MyIterable {}
impl MyIterable {
// In the real use-case I can't remove the 'mut'.
pub fn get_iter<'a>(&'a mut self) -> MyIter<'a> {
MyIter {
marker: PhantomData,
}
} …Run Code Online (Sandbox Code Playgroud) 我对 Rust 还比较陌生。我想编写一个函数,该函数将根据给定的闭包从集合创建 HashMap,该闭包从值生成键,例如
[derive(Debug)]
struct Foo {
id: u32,
name: String,
}
let foos = vec![
Foo { id: 1, name: "Bill".to_string() },
Foo { id: 2, name: "Mary".to_string() },
];
println!("{:?}", foos);
println!("{:?}", map_by(foos.iter(), |f| f.id)); // borrow the Foos
println!("{:?}", map_by(foos.iter(), |f| &f.name)); // borrow
println!("{:?}", map_by(foos.iter(), |f| f.name.as_str())); // borrow
println!("{:?}", map_by(foos, |f| f.id)); // consume the Foos
Run Code Online (Sandbox Code Playgroud)
我写了这个,它适用于上述用途:
fn map_by<I,K,V>(iterable: I, f: impl Fn(&V) -> K) -> HashMap<K,V>
where I: IntoIterator<Item = V>,
K: Eq …Run Code Online (Sandbox Code Playgroud) 我正在用 Rust 开发一个单词生成器。该应用程序由两个主要结构组成:Letter和Alphabet.
Letter 由单个字符和有关其与其他字母关系的规则组成。
Alphabet包含元音和辅音的向量以及引用这些向量中字母的哈希图。这样做是为了可以在 O(1) 时间内检索字母的规则。
我创建了一个工厂方法来从 json 字符串(下面的代码)中读取字母表,但是我收到一个错误,指出字母表实例的寿命不够长。
src/word_generator/alphabet.rs:47:6: 47:14 错误:
alphabet寿命不够长 src/word_generator/alphabet.rs:47alphabet.add_letter(letter);src/word_generator/alphabet.rs:26:40: 55:3 注意:参考必须对 26:39 在块上定义的匿名生命周期 #1 有效... src/word_generator/alphabet.rs:26 pub fn from_json (json: &str)->字母{
注意:...但借用的值仅对 40:37 src/word_generator/alphabet.rs:40 处的语句 3 后面的块后缀有效 let mut episode = Alphabet::new(); src/word_generator/alphabet.rs:41
我理解错误(我希望),但我不明白它为什么会发生。为什么Alphabet函数返回的 实例new()被变量借用了alphabet?这不是移动操作吗?
pub struct Alphabet<'a>{
pub vowels: Vec<Letter>,
pub consonants: Vec<Letter>,
letters: HashMap<char,&'a Letter>
}
impl<'a> Alphabet<'a>{
pub fn new()->Alphabet<'a>{
return Alphabet{
vowels: Vec::new(),
consonants: Vec::new(),
letters: …Run Code Online (Sandbox Code Playgroud) 我有两个结构.App和Item.
我想要实现的是通过将可变引用传递给s构造函数来在结构Item的items向量中存储.AppItem
pub struct App<'a> {
items: Vec<&'a Item>
}
impl<'a> App<'a> {
pub fn new() -> App<'a> {
App { items: Vec::new() }
}
pub fn register_item(&mut self, item: &'a Item) {
self.items.push(item);
}
}
pub struct Item;
impl Item {
pub fn new(app: &mut App) -> Item {
let item = Item;
app.register_item(&item);
item
}
}
fn main() {
let mut app = App::new();
let item = Item::new(&mut …Run Code Online (Sandbox Code Playgroud) 我有一个收藏Foo。
struct Foo {
k: String,
v: String,
}
Run Code Online (Sandbox Code Playgroud)
我想要一个HashMap具有键&foo.k和值的键foo。
显然,不Foo通过引入Rc或克隆/复制进行重新设计是不可能的k。
fn t1() {
let foo = Foo { k: "k".to_string(), v: "v".to_string() };
let mut a: HashMap<&str, Foo> = HashMap::new();
a.insert(&foo.k, foo); // Error
}
Run Code Online (Sandbox Code Playgroud)
get()从HashSet(Playground)滥用似乎有一种解决方法:
use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher, BuildHasher};
use std::collections::hash_map::Entry::*;
struct Foo {
k: String,
v: String,
}
impl PartialEq for Foo {
fn eq(&self, …Run Code Online (Sandbox Code Playgroud)