rust - `Option 的动态替换>>>`
问题描述
假设我有一个对象video_source: Option<Arc<Mutex<Box<dyn GetVideo>>>>
并将它传递给一个线程:
std::thread::spawn(||{
loop {
if let Some(video_source) = video_source {
let video_frame = video_source.lock().unwrap().get();
}
}
})
在哪里
trait GetVideo {
fn get() -> Vec<u8>
}
如果我想即时更改视频源怎么办?好吧,我会在另一个线程上这样做:
video_frame.unwrap().lock().unwrap() = Box::new(other_source);
我想让这个想法更通用。我想要一种允许这种事情的类型。这是我的草图:
use std::sync::{Arc, Mutex};
pub type OnTheFlyInner<T> = Box<T + Send + Sync>;
pub type OnTheFly<T> = Arc<Mutex<OnTheFlyInner<T>>>;
//I'd like this to be a method of `OnTheFly`
pub fn on_the_fly_substitute(on_the_fly: &mut Option<OnTheFly>, substitute_by: Option<OnTheFlyInner>) {
if let Some(substitute_by) = substitute_by {
if let Some(on_the_fly) = on_the_fly {
*on_the_fly.lock().unwrap() = substitute_by;
}
} else {
on_the_fly.take();
}
}
但是,我不能在T
哪里T
是特征,它应该是一种类型。
有任何想法吗?
赏金
@user4815162342 解决了这个问题。但是,如果我想让一个OnTheFly
对象指向与另一个对象相同的东西怎么办?
解决方案
首先,你是对的,T
不能像GetVideo
; 特征不是类型。不过,T
可以dyn GetVideo
。
其次,您的别名具有通用参数,因此它们应该反映在函数签名中:
pub fn on_the_fly_substitute<T>(on_the_fly: &mut Option<OnTheFly<T>>, substitute_by: Option<OnTheFlyInner<T>>)
^^^ ^^^ ^^^
第三,您的别名看起来像是试图限制 T
为Send
+ Sync
,但别名不能定义额外的 bounds。您可以将它们放在函数上(?Sized
因为您想允许特征对象):
pub fn on_the_fly_substitute<T: ?Sized>(on_the_fly: &mut Option<OnTheFly<T>>, substitute_by: Option<OnTheFlyInner<T>>)
where
T: ?Sized + Send + Sync
{
...
}
注意:您的函数体不需要Send
,Sync
因此可能不应该包括这些边界。
第四,Option<Arc<Mutex<Box<dyn GetVideo>>>>
不是线程安全的。您需要限制特征对象至少为Send
:
Option<Arc<Mutex<Box<dyn GetVideo + Send>>>>
^^^^^^
第五,缺少一个完整的示例,但您似乎希望多个线程修改相同的video_source
. 这可能无法编译,因为您需要多个线程来保留 a&mut _
才能更改它。
如果您希望共享一个可能不存在的值的所有权,请将选项移入Mutex
并相应地调整您的函数和别名:
video_source: Arc<Mutex<Option<Box<dyn GetVideo>>>>
第六,您的评论“我希望这是一种方法OnTheFly
”被误导了。别名只是别名,您需要一个别名Option
/Arc
类型的方法。将其保留为自由函数,为其引入扩展特征,或者如果您想要更细粒度的控制,则将其创建为包装类型而不是别名。
推荐阅读
- android - RetroFit 呼叫在第一次后失败
- vue.js - 无法使用 VueJS 登录 Auth0 SPA 中的某些用户
- c++ - 如何识别插槽中发出的信号?
- php - 将带有下拉菜单的文本插入数据库
- android - 如何在 Textview 中用文本填充整个空间?
- python - 导出为 CSV 文件
- javascript - 如何调用一个函数调用首先发生
- php - 获取“未定义的偏移量:2 错误(错误在:'participant_id' => $participants[$i]->id,)
- c++ - 我可以在调用期间从其目标函数中删除 std::function 对象吗?
- python - pandas 从 csv 文件中读取 MultiIndex 数据