< 返回版块

yueruijie 发表于 2021-06-22 20:02

Tags:求助

pub fn execute(&self, f: F) where F: FnOnce() + Send + 'static { let x = Box::new(f); self.sender.send(Message::NewJob(x)).expect("---------发送错误-------------") }

我有点不太理解这句话 关于多线程传递闭包的解释:一个线程不确定何时执行因此需要声明static 为什么一个闭包对象确定只使用一次 却要声明'static 常驻内存? 难道不是使用一次就销毁了吗

评论区

写评论
freedom967 2021-06-23 15:31

'static生命周期限定并不是意味着常驻内存,它指的尽可能活得长,rust编译器最终会给它一个确定的分配时间和析构时间

eweca-d 2021-06-23 14:23

按我的理解,是这样的。

--
👇
yueruijie: 也就是除非变量本身是static 的 否则依然会被正常回收 对吧

geek-frio 2021-06-23 13:28

看下crossbeam::thread::scope方法的源码实现,这里就不需要传一个'static。

作者 yueruijie 2021-06-23 09:33

也就是除非变量本身是static 的 否则依然会被正常回收 对吧

作者 yueruijie 2021-06-23 09:31

感谢!

eweca-d 2021-06-22 20:22

用makedown语法吧,这个代码块看着费劲,不过大概知道了你要说啥。

我搜索了一下,首先,这个'static是对闭包内参数的生命周期限制。一个解释如下:

The closure cannot borrow anything from its environment - it must consist of only owned data or references to 'static data (that’s the 'static requirement in the call_with_gvl signature). From the little you’ve said, I suspect your closure is borrowing from the environment. Can you show it?

意思是带有'static的trait bound意味着你的闭包内所有变量的所有权必须为闭包所有,或者该变量的生命周期必须是'static。这种做法是防止闭包在使用时,它捕获的变量却已经失效,从而导致程序错误。显然,是非常有必要的。


另外,根据如下回答,闭包是必须声明声明周期的,如下:

In fact, dyn types (trait object types) must have exactly one lifetime bound. It's inferred when omitted. The inference rule is described in RFC 0192 and RFC 1156. It's basically as follows:

If explicitly given, use that lifetime. Otherwise, it is inferred from the inner trait. For example, Box is Box<Any + 'static> because Any: 'static. If the trait doesn't have an appropriate lifetime, it is inferred from the outer type. For example, &'a Fn() is &'a (Fn() + 'a). If that even failed, it falls back to 'static (for a function signature) or an anonymous lifetime (for a function body).

所以这就是为什么'static出现在这里的原因。显然,闭包被drop时候(闭包本身不是'static的),里面的所有变量(除了'static外),都会被丢弃,所以不存在占用内存的情况。我一般就是直接写'static,免得和编译器斗智斗勇。

1 共 6 条评论, 1 页