相关疑难解决方法(0)

拥有一些数据和对该数据的引用的结构

对象的构造会分配该对象生命周期所需的数据,但还会创建另一个需要保留对数据的引用的对象:

pub fn new() -> Obj {
    let data = compute();

    Obj {
        original: data,
        processed: AnotherObj {
            reference: &data
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是否可以用Rust的术语表达这一点?

在这里,我想要ObjAnotherObj并且data拥有相同的生命周期,当然还没有new()通话。

object-lifetime rust borrow-checker

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

何时以及如何使用引用向量

此代码正确编译.它有一些未使用的代码警告,但现在没问题.

use std::collections::BTreeMap;

enum Object<'a> {
    Str(String),
    Int(i32),
    Float(f32),
    Vector(Vec<&'a Object<'a>>),
    Prim(fn(State) -> State)
}

struct State<'a> {
    named: BTreeMap<String, &'a Object<'a>>,
    stack: Vec<Object<'a>>

}

impl<'a> State<'a> {
    fn push_int(&mut self, x: i32) {
        self.stack.push(Object::Int(x));
    }
}


fn main() {
    println!("Hello, world!");
    let obj = Object::Str("this is a test".to_string());
}
Run Code Online (Sandbox Code Playgroud)

这段代码的重要部分是push_intstack: Vec<Object<'a>>.

我正在尝试制作基于堆栈的VM.我想将状态传递给函数,函数可以从堆栈中取出东西,操作东西,然后将一些东西放回堆栈; 命名字段将保存命名对象.

我有一种预感,将堆栈表示为Vec<&'a Object<'a>>替代会更好.我现在拥有它的方式,我担心我会犯一些效率低下的错误.我的预感是正确的吗?

问题的第二部分是我不知道如何使引用版本的矢量工作.以适当的生命周期创建新值以推入堆栈对我来说不起作用.

我对这个问题有点模糊,所以如果我一直不清楚,请问我问题以清除问题.

reference vector rust

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

Rust 中带有 RwLockGuard 的 HashMap 记录的游标

我是 Rust 的新手,我正在尝试实现一个简单的、线程安全的内存键值存储,HashMapRwLock. 我的代码如下所示:

use std::sync::{ Arc, RwLock, RwLockReadGuard };
use std::collections::HashMap;
use std::collections::hash_map::Iter;

type SimpleCollection = HashMap<String, String>;

struct Store(Arc<RwLock<SimpleCollection>>);

impl Store {
    fn new() -> Store { return Store(Arc::new(RwLock::new(SimpleCollection::new()))) }

    fn get(&self, key: &str) -> Option<String> {
        let map = self.0.read().unwrap();
        return map.get(&key.to_string()).map(|s| s.clone());
    }

    fn set(&self, key: &str, value: &str) {
        let mut map = self.0.write().unwrap();
        map.insert(key.to_string(), value.to_string());
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,这段代码工作正常。问题是我正在尝试实现一个scan()函数,该函数返回一个Cursor可用于迭代所有记录的对象。我希望Cursor对象持有一个RwLockGuard,它在游标本身被释放之前不会被释放(基本上我不想在游标处于活动状态时允许修改)。

我试过这个:

use ...

type …
Run Code Online (Sandbox Code Playgroud)

rust rwlock

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

在结构体中传递 Mutex 和 MutexGuard

我试图返回一个包含对共享互斥体的引用的结构:

struct Test<'a> {
    mutex: Arc<Mutex<()>>,
    guard: &'a MutexGuard<'a, ()>,
}

impl<'a> Test<'a> {
    pub fn new() -> Self {
        let mutex = Arc::new(Mutex::new(()));
        let guard = &mutex.lock().unwrap();
        Self {
            mutex,
            guard,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

生命周期似乎是正确的:互斥体至少在 的生命周期内存在Test,因此MutexGuard没有对互斥体的停滞引用。但 Rust 给出了错误。如何向 Rust 解释字段的生命周期mutex足够长,可以guard正常工作?

cannot return value referencing local variable `mutex`
returns a value referencing data owned by the current function
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我正在尝试创建一个“mutli-mutex” - 一组键的互斥体(如 中所示HashMap),以阻止下载名称在 hashmap 中的文件(因为它已经在下载)。

mutex lifetime rust automatic-ref-counting

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

在不安全的 Rust 中存储对结构内部数据的静态引用是否合法?

我有以下数据结构(简化):

use std::collections::HashMap;
pub struct StringCache {
    // the hashmap keys point to elements stored in `storage`
    // so never outlive this datastructure. the 'static refs are never handed out
    table: HashMap<&'static str, usize>,

    storage: Vec<Box<str>>,
}
Run Code Online (Sandbox Code Playgroud)

关于此处引用的生命周期向 Rust“撒谎”是合法/定义的行为吗?对我来说,这感觉就像违反了类型系统。这个数据结构的公共API健全吗?为了完整起见,以下是完整的实现:

use std::mem::transmute;
impl StringCache {
    pub fn intern(&mut self, entry: &str) -> usize {
        if let Some(key) = self.table.get(entry) {
            return *key;
        }
        let idx = self.storage.len();
        self.storage.push(entry.to_owned().into_boxed_str());
        // we cast our refs to 'static here.
        let key = …
Run Code Online (Sandbox Code Playgroud)

unsafe lifetime language-lawyer rust

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

将两个对象(其中一个包含对另一个对象的引用)传递到线程中

我有两个对象,第二个对象要求第一个对象比它更长,因为它包含对第一个对象的引用.我需要将它们都移动到一个线程中,但编译器抱怨第一个没有足够长的时间.这是代码:

use std::thread;

trait Facade: Sync {
    fn add(&self) -> u32;
}

struct RoutingNode<'a> {
    facade: &'a (Facade + 'a),
}

impl<'a> RoutingNode<'a> {
    fn new(facade: &'a Facade) -> RoutingNode<'a> {
        RoutingNode { facade: facade }
    }
}

fn main() {
    struct MyFacade;

    impl Facade for MyFacade {
        fn add(&self) -> u32 {
            999u32
        }
    }

    let facade = MyFacade;
    let routing = RoutingNode::new(&facade);

    let t = thread::spawn(move || {
        let f = facade;
        let r = routing;
    });

    t.join(); …
Run Code Online (Sandbox Code Playgroud)

reference lifetime move-semantics rust lifetime-scoping

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

如何将拥有的装箱结构引用到其他拥有的结构

我拥有Engine它,Worker并且我想Engine提供一些 API 作为Worker对特征的引用。API 实现是使用 分配Box并由 拥有的Engine,因此只要工作进程还活着,对它的引用就是稳定且有效的。

但我不明白如何用 Rust 表达它。

我已阅读为什么不能在同一结构中存储值和对该值的引用?我明白为什么我不能传递对拥有价值的引用。但是,就我而言,我传递的不是对拥有值本身的引用,而是对装箱值的引用,该值不会被移动,因此对它的引用必须是稳定的。

这是非工作原型:

trait EngineApi {
    fn foo(&self);
}

struct Worker<'a> {
    api: &'a EngineApi,
}
impl<'a> Worker<'a> {
    fn new(engine_api: &'a EngineApi) -> Self {
        Worker { api: engine_api }
    }
}

struct Api;
impl EngineApi for Api {
    fn foo(&self) {} 
}

struct Engine<'a> {
    api: Box<Api>,
    worker: Box<Worker<'a>>,
}

impl<'a> Engine<'a> {
    fn new() -> …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

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

在将结构插入地图而不重复它时,如何使用struct的成员作为自己的键?

是否可以在映射中插入一个结构,其中键由插入的值所拥有?

在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其他上下文,可能会适得其反).

rust borrow-checker

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

使用父指针创建 Rust 树的典型方法是什么?

我需要定义一个二叉搜索树,其中每个节点都可以访问父节点:

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)

pointers binary-search-tree rust

5
推荐指数
0
解决办法
2204
查看次数

是否拥有String :: chars的所有版本?

以下代码无法编译:

use std::str::Chars;

struct Chunks {
    remaining: Chars,
}

impl Chunks {
    fn new(s: String) -> Self {
        Chunks {
            remaining: s.chars(),
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

错误是:

use std::str::Chars;

struct Chunks {
    remaining: Chars,
}

impl Chunks {
    fn new(s: String) -> Self {
        Chunks {
            remaining: s.chars(),
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Chars不拥有要迭代的字符,也不能超过其&strString从其创建的字符。

是否存在Chars不需要生存期参数的私有版本,或者我必须自己保留Vec<char>和索引?

string iterator ownership rust

5
推荐指数
3
解决办法
632
查看次数