我有一个对象,我知道它在 an 内部,Arc因为所有实例总是Arced。我希望能够Arc在函数调用中传递我自己的克隆。我正在调用的东西稍后会在其他线程上给我回电。
在 C++ 中,有一个标准的 mixin 叫做enable_shared_from_this. 它使我能够做到这一点
class Bus : public std::enable_shared_from_this<Bus>
{
....
void SetupDevice(Device device,...)
{
device->Attach(shared_from_this());
}
}
Run Code Online (Sandbox Code Playgroud)
如果此对象不受shared_ptr管理(最接近的 C++ 必须Arc),那么这将在运行时失败。
我找不到等价物。
编辑:
这是一个为什么需要它的例子。我有一个定时器队列库。它允许客户端请求在将来的某个时间点运行任意闭包。代码在专用线程上运行。要使用它,您必须传递要稍后执行的函数的闭包。
use std::time::{Duration, Instant};
use timerqueue::*;
use parking_lot::Mutex;
use std::sync::{Arc,Weak};
use std::ops::{DerefMut};
// inline me keeper cos not on github
pub struct MeKeeper<T> {
them: Mutex<Weak<T>>,
}
impl<T> MeKeeper<T> {
pub fn new() -> Self {
Self {
them: Mutex::new(Weak::new()),
}
}
pub fn save(&self, arc: &Arc<T>) {
*self.them.lock().deref_mut() = Arc::downgrade(arc);
}
pub fn get(&self) -> Arc<T> {
match self.them.lock().upgrade() {
Some(arc) => return arc,
None => unreachable!(),
}
}
}
// -----------------------------------
struct Test {
data:String,
me: MeKeeper<Self>,
}
impl Test {
pub fn new() -> Arc<Test>{
let arc = Arc::new(Self {
me: MeKeeper::new(),
data: "Yo".to_string()
});
arc.me.save(&arc);
arc
}
fn task(&self) {
println!("{}", self.data);
}
// in real use case the TQ and a ton of other status data is passed in the new call for Test
// to keep things simple here the 'container' passes tq as an arg
pub fn do_stuff(&self, tq: &TimerQueue) {
// stuff includes a async task that must be done in 1 second
//.....
let me = self.me.get().clone();
tq.queue(
Box::new(move || me.task()),
"x".to_string(),
Instant::now() + Duration::from_millis(1000),
);
}
}
fn main() {
// in real case (PDP11 emulator) there is a Bus class owning tons of objects thats
// alive for the whole duration
let tq = Arc::new(TimerQueue::new());
let test = Test::new();
test.do_stuff(&*tq);
// just to keep everything alive while we wait
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
}
Run Code Online (Sandbox Code Playgroud)
货物 toml
[package]
name = "tqclient"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
timerqueue = { git = "https://github.com/pm100/timerqueue.git" }
parking_lot = "0.11"
Run Code Online (Sandbox Code Playgroud)
有没有办法从去&self到Arc那个self被存储在。这是因为:
Arc甚至没有公开确定是否self存储在Arc.幸运的是,有一种替代方法。与其为&self中的值创建 aArc并将其传递给方法,不如Arc直接将传递给需要访问它的方法。你可以这样做:
use std::sync::Arc;
struct Shared {
field: String,
}
impl Shared {
fn print_field(self: Arc<Self>) {
let clone: Arc<Shared> = self.clone();
println!("{}", clone.field);
}
}
Run Code Online (Sandbox Code Playgroud)
那么该print_field函数只能在Shared封装在Arc.
| 归档时间: |
|
| 查看次数: |
287 次 |
| 最近记录: |