这些是我可以想出的方法来尝试匹配引用计数的内部可变枚举:
#![allow(unused)]
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug, Clone, PartialEq)]
struct Bar {
some_bar: Vec<f64>,
}
#[derive(Debug, Clone, PartialEq)]
struct Baz {
some_baz: i32,
}
#[derive(Debug, Clone, PartialEq)]
enum Foo {
Bar(Bar),
Baz(Baz),
}
fn is_baz(foo_ref: Rc<RefCell<Foo>>) -> bool {
match foo_ref {
Foo::Bar(_) => false,
Foo::Baz(_) => true,
}
}
fn is_baz_borrow(foo_ref: Rc<RefCell<Foo>>) -> bool {
match foo_ref.borrow() {
Foo::Bar(_) => false,
Foo::Baz(_) => true,
}
}
fn is_baz_deref(foo_ref: Rc<RefCell<Foo>>) -> bool {
match *foo_ref {
Foo::Bar(_) => false,
Foo::Baz(_) …Run Code Online (Sandbox Code Playgroud) 我有一个结构体,其字段定义如下:
log_str: RefCell<String>
Run Code Online (Sandbox Code Playgroud)
我在现场进行了各种呼叫borrow_mut()。push_str(.)最后,我使用以下方法评估其价值:
assert_eq!(os.log_str.borrow(), "<expected value>");
Run Code Online (Sandbox Code Playgroud)
尽管如此,断言行还是会引发编译时错误,并显示以下消息:
错误[E0369]:二进制运算
==不能应用于类型std::cell::Ref<'_, std::string::String>
我明白为什么会发生错误,因为编译器甚至提示:
std::cmp::PartialEq可能缺少以下实现std::cell::Ref<'_, std::string::String>
我的问题是:我应该如何比较 a 中包含的值RefCell<T>(通常在这种情况下,将包含的字符串与预期值进行比较)。
谢谢 !
我试图环绕我的头Rc,并RefCell在生锈.我想要实现的是对同一个对象进行多个可变引用.
我想出了这个虚拟代码:
use std::rc::Rc;
use std::cell::RefCell;
struct Person {
name: String,
mother: Option<Rc<RefCell<Person>>>,
father: Option<Rc<RefCell<Person>>>,
partner: Option<Rc<RefCell<Person>>>
}
pub fn main () {
let mut susan = Person {
name: "Susan".to_string(),
mother: None,
father: None,
partner: None
};
let mut boxed_susan = Rc::new(RefCell::new(susan));
let mut john = Person {
name: "John".to_string(),
mother: None,
father: None,
partner: Some(boxed_susan.clone())
};
let mut boxed_john = Rc::new(RefCell::new(john));
let mut fred = Person {
name: "Fred".to_string(),
mother: Some(boxed_susan.clone()),
father: Some(boxed_john.clone()),
partner: …Run Code Online (Sandbox Code Playgroud) 如果Mutex<T>设计Arc<T>使用a的唯一原因Mutex<T>是用于并发代码(即多个线程),为什么还要设计一个?首先将a别名Mutex<T>为原子引用会更好吗?我正在使用https://doc.rust-lang.org/book/ch16-03-shared-state.html作为参考。
我一直在思考为什么 Rust 中的内部可变性在大多数情况下需要运行时检查(例如RefCell)。看起来我找到了一个没有运行时成本的安全替代方案。我已经调用了该类型SafeCell(主要是因为它是一个安全的包装器UnsafeCell),它允许您将任何函数应用于包装的值,而没有引用转义的风险:
struct SafeCell<T> {
inner: UnsafeCell<T>,
}
impl<T> SafeCell<T> {
pub fn new(value: T) -> Self {
Self {
inner: UnsafeCell::new(value),
}
}
pub fn apply<R, F>(&self, fun: F) -> R
where
F: FnOnce(&mut T) -> R,
{
// Reference below has a lifetime of the current scope, so if
// user tries to save it somewhere, borrow checker will catch this.
let reference: &mut T = unsafe { &mut *self.inner.get() }; …Run Code Online (Sandbox Code Playgroud) 我无法将参数传递给 fn。
trait T {}
struct S {
others: Vec<Rc<RefCell<dyn T>>>
}
impl S {
fn bar(&self) {
for o in self.others {
foo(&o.borrow());
}
}
}
fn foo(t: &dyn T) {}
Run Code Online (Sandbox Code Playgroud)
编译器告诉我:
trait T {}
struct S {
others: Vec<Rc<RefCell<dyn T>>>
}
impl S {
fn bar(&self) {
for o in self.others {
foo(&o.borrow());
}
}
}
fn foo(t: &dyn T) {}
Run Code Online (Sandbox Code Playgroud)
我认为这就像在rust 书中的示例中,其中Rc自动取消引用并从我可以调用的 RefCell 中获取值borrow()。
我也尝试过显式取消引用,但似乎没有任何效果。
如何调用foo()中的每个dyn T对象 …
假设我想要一个train可以随时在两个轨道之一之间切换并u8在其当前位置写入 a 的轨道。天真地是这样的:
struct Train<'a> {
track_a: &'a mut [u8],
track_b: &'a mut [u8],
current_track: &'a mut [u8], // either track_a or track_b
idx: usize,
}
impl<'a> Train<'a> {
pub fn new(track_a: &'a mut [u8], track_b: &'a mut [u8]) -> Self {
Self {
track_a,
track_b,
idx: 0,
current_track: track_a,
}
}
pub fn toggle_track(&mut self) {
if self.current_track == self.track_a {
self.current_track = self.track_b;
} else {
self.current_track = self.track_a;
}
}
pub fn write(&mut …Run Code Online (Sandbox Code Playgroud) 我想解决Rust中的leetcode问题(从列表末尾删除第N个节点).我的解决方案使用两个指针来查找Node要删除的内容:
#[derive(PartialEq, Eq, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode { next: None, val }
}
}
// two-pointer sliding window
impl Solution {
pub fn remove_nth_from_end(head: Option<Box<ListNode>>, n: i32) -> Option<Box<ListNode>> {
let mut dummy_head = Some(Box::new(ListNode { val: 0, next: head }));
let mut start = dummy_head.as_ref();
let mut end = dummy_head.as_ref();
for _ in 0..n {
end …Run Code Online (Sandbox Code Playgroud)