是否有可能使这个 Rust 代码更容易推理?

asd*_*bgt 1 rust tauri

我正在阅读这段 Rust 代码,但我几乎没有能力理解所有互斥体和句柄的情况。为了让 Rust 诸神高兴,这一切都是多余的,而且这让他们很难专注于实际发生的事情。看一看:

#[tauri::command]
fn spawn(param: String, window: Window<Wry>) {
    let window_arc = Arc::new(Mutex::new(window));

    // Spawn bin
    let (mut rx, child) = tauri::api::process::Command::new_sidecar("bin")
        .expect("failed to create binary command")
        .args([param])
        .spawn()
        .expect("Failed to spawn sidecar");
    let child_arc = Arc::new(Mutex::new(child));

    // Handle data from bin
    let window = window_arc.clone();
    let (handle, mut handle_rx) = broadcast::channel(1);
    let handle_arc = Arc::new(Mutex::new(handle));
    tauri::async_runtime::spawn(async move {
        loop {
            tokio::select! {
                _ = handle_rx.recv() => {
                    return;
                }
                Some(event) = rx.recv() => {
                    if let CommandEvent::Stdout(line) = &event {
                        let data = decode_and_xor(line.clone());
                        println!("Data from bin: {}", data);
                        window.lock().unwrap().emit("from_bin", data).expect("failed to emit message");
                    }
                    if let CommandEvent::Stderr(line) = &event {
                        println!("Fatal error bin: {}", &line);
                        window.lock().unwrap().emit("bin_fatal_error", line).expect("failed to emit message");
                    }
                }
            }
            ;
        }
    });
    let window = window_arc.clone();
    let window_cc = window.clone();
    window_cc.lock().unwrap().listen("kill_bin", move |event| {
        let handle = handle_arc.clone();
        handle.lock().unwrap().send(true).unwrap();
        window.lock().unwrap().unlisten(event.id());
    });

    // Handle data to bin
    let window = window_arc.clone();
    tauri::async_runtime::spawn(async move {
        let child_clone = child_arc.clone();
        let (handle, handle_rx) = broadcast::channel(1);
        let handle_rx_arc = Arc::new(Mutex::new(handle_rx));
        let handle_arc = Arc::new(Mutex::new(handle));
        let window_c = window.clone();
        window.lock().unwrap().listen("to_bin", move |event| {
            let handle_rx = handle_rx_arc.clone();
            if handle_rx.lock().unwrap().try_recv().is_ok() {
                window_c.lock().unwrap().unlisten(event.id());
                return;
            }
            // Send data to bin
            let payload = String::from(event.payload().unwrap());
            let encrypted = xor_and_encode(payload) + "\n";
            println!("Data to send: {}", event.payload().unwrap());
            child_clone.clone().lock().unwrap().write(encrypted.as_bytes()).expect("could not write to child");
        });
        let window_c = window.clone();
        window.lock().unwrap().listen("kill_bin", move |event| {
            let handle = handle_arc.clone();
            handle.lock().unwrap().send(true).unwrap();
            window_c.lock().unwrap().unlisten(event.id());
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

所有这些弧线、互斥体和克隆都是必要的吗?我该如何以 Rust 惯用的方式清理这个问题,以便更容易地了解发生了什么?

Mas*_*inn 6

所有这些弧线、互斥体和克隆都是必要的吗?

可能不是,您似乎过度克隆并重新包装并发结构,但您必须查看特定的 API

例如,假设broascast::channelTokio 是为并发使用而设计的(这就是重点),因此发送方被设计为可克隆(对于多个生产者),并且您可以根据需要从发送方创建尽可能多的接收方。

不需要用弧形包裹,特别是不需要用锁来保护它们,它们被设计为按原样工作。

此外,在这种情况下,它甚至没有必要,因为您只有一个发送者任务和一个接收者任务,两者都不是共享的。使用它们时也不需要克隆它们。所以例如

    let handle_arc = Arc::new(Mutex::new(handle));
    [...]
    window_cc.lock().unwrap().listen("kill_bin", move |event| {
        let handle = handle_arc.clone();
        handle.lock().unwrap().send(true).unwrap();
        window.lock().unwrap().unlisten(event.id());
    });
Run Code Online (Sandbox Code Playgroud)

我很确定可以

    window_cc.lock().unwrap().listen("kill_bin", move |event| {
        handle.send(true).unwrap();
        window.lock().unwrap().unlisten(event.id());
    });
Run Code Online (Sandbox Code Playgroud)

这就是封口里面的move内容handle,然后发送出去。Sender内部是可变的,因此它不需要锁定来发送事件(这宁愿破坏这一点)。