簡體   English   中英

如何將通用 T 發送到另一個線程?

[英]How to send generic T to another thread?

如何發送通用T

我嘗試將通用T發送到另一個線程,但我得到:

error[E0308]: mismatched types
  --> src/main.rs:23:22
   |
23 |             t1.merge(Element(vec![3]));
   |                      ^^^^^^^^^^^^^^^^ expected associated type, found struct `Element`
   |
   = note: expected associated type `<T as Join>::Item`
                       found struct `Element`
   = help: consider constraining the associated type `<T as Join>::Item` to `Element`

完整代碼:

trait Join {
    type Item;
    fn merge(&mut self, other: Self::Item);
}

#[derive(Debug, Default)]
struct Element(Vec<u8>);

impl Join for Element {
    type Item = Element;
    fn merge(&mut self, mut other: Self::Item) {
        self.0.append(&mut other.0);
    }
}

fn work<T>()
where
    T: Default + Join + Send + Sync + 'static,
{
    let (sender, receiver) = std::sync::mpsc::channel::<(T)>();
    std::thread::spawn(move || {
        while let (mut t1) = receiver.recv().unwrap() {
            t1.merge(Element(vec![3]));
        }
    });

    loop {
        let mut t1 = T::default();
        sender.send(t1);
        std::thread::sleep(std::time::Duration::from_secs(5));
    }
}

fn main() {
    // works!
    let mut e = Element(vec![1]);
    e.merge(Element(vec![2]));

    // bad!
    work::<Element>();
}

游樂場鏈接

當您使用 generics 時,您讓調用者決定您的通用 function 必須使用哪些類型。

您的示例中的這一行t1.merge(Element(vec;[3])); 是無效的,因為它假定T = Element但調用者可以從無限多種可能的T類型中進行選擇,其中T != Element這就是編譯器抱怨的原因。

要使您的 function 完全通用,您必須執行一些操作,例如在 function 簽名中添加Default綁定到<T as Join>::Item ,然后將違規行更改為t1.merge(<T as Join>::Item::default()); .

更新的工作注釋示例:

use std::fmt::Debug;

trait Join {
    type Item;
    fn merge(&mut self, other: Self::Item);
}

#[derive(Debug)]
struct Element(Vec<u8>);

// updated Default impl so we can observe merges
impl Default for Element {
    fn default() -> Self {
        Element(vec![1])
    }
}

impl Join for Element {
    type Item = Element;
    fn merge(&mut self, mut other: Self::Item) {
        self.0.append(&mut other.0);
    }
}

fn work<T>() -> Result<(), Box<dyn std::error::Error>>
where
    T: Default + Join + Send + Sync + Debug + 'static,
    <T as Join>::Item: Default, // added Default bound here
{
    let (sender, receiver) = std::sync::mpsc::channel::<T>();
    std::thread::spawn(move || {
        while let Ok(mut t1) = receiver.recv() {
            // changed this to use Default impl
            t1.merge(<T as Join>::Item::default());

            // prints "Element([1, 1])" three times
            println!("{:?}", t1);
        }
    });

    let mut iterations = 3;
    loop {
        let t1 = T::default();
        sender.send(t1)?;
        std::thread::sleep(std::time::Duration::from_millis(100));
        iterations -= 1;
        if iterations == 0 {
            break;
        }
    }

    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // works!
    let mut e = Element(vec![1]);
    e.merge(Element(vec![2]));

    // now also works!
    work::<Element>()?;

    Ok(())
}

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM