为何忽略info参数的闭包仍能满足async_task的Schedule trait约束?
问题:async_task中仅接收Runnable的闭包如何满足Schedule trait约束?
我在查看async_task库的spawn_local文档时,注意到示例代码如下:
use async_task::Runnable; use flume::{Receiver, Sender}; use std::rc::Rc; thread_local! { // A queue that holds scheduled tasks. static QUEUE: (Sender<Runnable>, Receiver<Runnable>) = flume::unbounded(); } // Make a non-Send future. let msg: Rc<str> = "Hello, world!".into(); let future = async move { println!("{}", msg); }; // A function that schedules the task when it gets woken up. let s = QUEUE.with(|(s, _)| s.clone()); let schedule = move |runnable| s.send(runnable).unwrap(); // Create a task with the future and the schedule function. let (runnable, task) = async_task::spawn_local(future, schedule);
spawn_local的函数签名对Schedule trait有约束:
pub fn spawn_local<F, S>(future: F, schedule: S) -> (Runnable, Task<F::Output>) where F: Future + 'static, F::Output: 'static, S: Schedule + Send + Sync + 'static,
其中Schedule trait定义如下:
pub trait Schedule<M = ()>: Sealed<M> { // Required method fn schedule(&self, runnable: Runnable<M>, info: ScheduleInfo); }
示例中的闭包let schedule = move |runnable| s.send(runnable).unwrap();未接收info: ScheduleInfo参数,想知道它是如何满足该trait约束的。
解答
这是因为async_task库为不同参数数量的闭包提供了Schedule trait的自动适配实现。
Schedule trait要求的schedule方法包含三个参数:&self、runnable、info,但Rust的闭包支持自动适配参数更少的场景——当你定义一个仅接收runnable的闭包时,库内部会自动生成对应的Schedule实现,在调用时直接忽略掉多余的info参数,相当于帮你补全了如下逻辑:
impl<F> Schedule for F where F: Fn(Runnable), { fn schedule(&self, runnable: Runnable, _info: ScheduleInfo) { self(runnable); } }
借助这种适配,你的闭包不需要显式处理info参数,也能满足Schedule trait的约束。
内容的提问来源于stack exchange,提问作者cogle
相关产品推荐
相关产品推荐

