我有一个类型,将其数据存储在 a 后面的容器中Rc<RefCell<>>,该容器大部分对公共 API 是隐藏的。例如:
struct Value;
struct Container {
storage: Rc<RefCell<HashMap<u32, Value>>>,
}
impl Container {
fn insert(&mut self, key: u32, value: Value) {
self.storage.borrow_mut().insert(key, value);
}
fn remove(&mut self, key: u32) -> Option<Value> {
self.storage.borrow_mut().remove(&key)
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
但是,查看容器内部需要返回Ref. 这可以通过使用来实现Ref::map()- 例如:
// peek value under key, panicking if not present
fn peek_assert(&self, key: u32) -> Ref<'_, Value> {
Ref::map(self.storage.borrow(), |storage| storage.get(&key).unwrap())
}
Run Code Online (Sandbox Code Playgroud)
但是,我想要一个非恐慌版本的peek,它会返回Option<Ref<'_, Value>>。这是一个问题,因为Ref::map要求您返回对 内存在的内容的引用 …
简介:我是 Rust 新手,所以我决定通过实现双链表来练习。出于调试目的,我实现了该get()方法,但未能从Rc<RefCell<_>>. (抱歉问了个愚蠢的问题)
问题:我试图返回一个Result<T, &'static str>in ,.get()其中T是节点中存储的数据的类型,&str是错误消息字符串。借用检查器告诉我,我无法返回对方法内变量的引用,因此我尝试将内部值复制出来并返回它,但失败了。
源代码:
use std::{rc::Rc, cell::RefCell};
struct Node<T> {
data: Option<T>,
prev: Option<Rc<RefCell<Node<T>>>>,
next: Option<Rc<RefCell<Node<T>>>>,
}
impl<T> Node<T> {
/// Instantiate a new dummy node.
/// This node is used to mark the start and end of the list.
/// It is not counted in the size of the list.
fn new() -> Self {
Node {
data: None, …Run Code Online (Sandbox Code Playgroud) 我有一个第三方库的函数,需要变量的所有权。不幸的是这个变量在Rc<RefCell<Option<Foo>>>.
我的代码看起来像这样简化:
use std::cell::RefCell;
use std::rc::Rc;
pub struct Foo {
val: i32,
}
fn main() {
let foo: Rc<RefCell<Option<Foo>>> = Rc::new(RefCell::new(Some(Foo { val: 1 })));
if let Some(f) = foo.into_inner() {
consume_foo(f);
}
}
fn consume_foo(f: Foo) {
println!("Foo {} consumed", f.val)
}
Run Code Online (Sandbox Code Playgroud)
use std::cell::RefCell;
use std::rc::Rc;
pub struct Foo {
val: i32,
}
fn main() {
let foo: Rc<RefCell<Option<Foo>>> = Rc::new(RefCell::new(Some(Foo { val: 1 })));
if let Some(f) = foo.into_inner() {
consume_foo(f);
}
}
fn consume_foo(f: Foo) …Run Code Online (Sandbox Code Playgroud) Rust 中的结构体std::cell::Ref定义如下:
pub struct Ref<'b, T: ?Sized + 'b> {
// NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
// `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
// `NonNull` is also covariant over `T`, just like we would have with `&T`.
value: NonNull<T>,
borrow: BorrowRef<'b>,
}
Run Code Online (Sandbox Code Playgroud)
评论// NB(我假设 Nota bene / Nasty Bug 或其他什么?)暗示以下定义不起作用,因为这会违反noalias(它们是否意味着后端的 LLVM 属性?):
pub struct Ref2<'b, T: ?Sized …Run Code Online (Sandbox Code Playgroud) 我的目标是将针对我的结构的方法调用委托给 Trait 的方法,其中 Trait 对象位于 ofRc内部RefCell。
我尝试遵循这个问题的建议: How can I acquire an &A reference from a Rc<RefCell<A>>?
我收到编译错误。
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt::*;
use std::ops::Deref;
pub struct ShyObject {
pub association: Rc<RefCell<dyn Display>>
}
impl Deref for ShyObject {
type Target = dyn Display;
fn deref<'a>(&'a self) -> &(dyn Display + 'static) {
&*self.association.borrow()
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
这是错误:
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt::*;
use std::ops::Deref;
pub struct ShyObject {
pub association: Rc<RefCell<dyn …Run Code Online (Sandbox Code Playgroud) 我用 Rust 做了服务器更新。它在两个二进制文件之间创建补丁,并提供静态文件
我尝试做
let mut update_state;
if let Some(state) = update_stream.next().await {
if let Ok(state) = state {
update_state = state
} else if let Err(err) = state {
reply = BuildOutput { error: "Update failed: ".to_string() + &err.to_string() }
}
} else {
reply = BuildOutput { error: "Unreacheable".to_string() }
}
let state = update_state.borrow();
let progress = state.histogram.progress();
let res = update_stream.try_for_each(|_state| future::ready(Ok(()))).await;
Run Code Online (Sandbox Code Playgroud)
但得到
note: future is not `Send` as this value is used across an await …Run Code Online (Sandbox Code Playgroud) 我为leetcode相同树问题编写了此代码:
use std::cell::RefCell;
use std::rc::Rc;
// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
struct Solution;
impl Solution {
pub fn is_same_tree(
p: Option<Rc<RefCell<TreeNode>>>,
q: Option<Rc<RefCell<TreeNode>>>,
) -> bool {
match (p, q) {
(None, None) => true,
(Some(p), Some(q)) if p.borrow().val …Run Code Online (Sandbox Code Playgroud) 我手动定义一个结构并为其MyData实现PartialEq和特征。Hash
我定义了一个枚举,其中包括Rc<MyData>和Rc<RefCell<MyData>>。
我想要为枚举导出PartialEqand ,但失败了:Hash
PartialEq都Hash适用于Rc<MyData>;PartialEq于Rc<RefCell<MyData>>;Hash不起作用Rc<RefCell<MyData>>!我有两个问题:
为什么?为什么只有Hash不起作用Rc<RefCell<MyData>>?
如何修复它?
我无法Hash实施Rc<RefCell<MyData>>. 经过搜索后,我找到了一种方法:定义一个新的包装结构,例如struct RRWrapper<T> (Rc<RefCell<T>>),然后实现Hashthis RRWrapper。但这会带来很多代码。有惯用的方法吗?我认为这是一般用法。
预先感谢,
吴
Rc<RefCell<MyData>>PS:在我程序的实际代码中,只有枚举中有,但没有Rc<MyData>。我放在Rc<MyData>这里只是为了比较。Rc<RefCell<T>>PS2:在我的程序的实际代码中,枚举中有多个。
原始源代码:
use std::rc::Rc;
use std::cell::RefCell;
use std::hash::{Hash, Hasher};
struct MyData {
i: i64,
}
impl Hash …Run Code Online (Sandbox Code Playgroud) 以下代码给出了“分配借用”错误。编译器如何知道这一点?编译器是否对 RefCell 进行了特殊封装,或者语言中是否有某些内容允许它告诉编译器您有借用的值?
use std::cell::RefCell;
fn main() {
let mut a = RefCell::new(A{a:5});
let mut b = a.borrow_mut();
a = RefCell::new(A{a:6});
}
Run Code Online (Sandbox Code Playgroud)
另外,为什么这段代码的工作似乎在做完全相同的事情?
use std::cell::RefCell;
fn main() {
let mut a = Box::new(A{a:5});
let mut b = &mut a;
a = Box::new(A{a:6});
}
Run Code Online (Sandbox Code Playgroud)