Type of tx channel variable

Hello,

I want to send a message via sync::mspc which works very well in my code.

Message looks as follows

// just an example
pub struct UserData{
    pub guard1 : bool,
} 

pub struct Message<T> {
    pub ev: u8,
    pub some_data: T,
}

I create a channel like that:
let (tx, rx) = mpsc::channel();

And then send messages from my main tread to a worker thread.

Message is as follows:
let mut msg = Message {ev: 0, some_data: true};

Now I want to hand over the tx (Sender) via a function.
But I'm unable to find out what data type tx actually has to write
the function correctly.

Thank you
Peter

The type will be mpsc::Sender<Message<bool>>, if you send your let mut msg. Or maybe you meant to include UserData as some_data, in which case the type would be mpsc::Sender<Message<UserData>> but msg is declared incorrectly.

Eventually you will learn how to discover this from the documentation. Another trick is to write a type error on purpose:

let _: () = tx;

The compiler's type error will tell you what the type of tx is.

Maybe I still have a lack of understanding of rust concepts because I come from (embedded) C. Used also lot of Java where I always have to specify template types. But reading channel in std::sync::mpsc - Rust there is no word telling what the template parameter T should be used for.

Also all the examples do not specify T but let the compiler deduct what type is used based on the later usage (this is my understanding - hopefully correct). For beginners this is not easy to understand. Having an example that specifies the message type in the creation of the channel would have helped me a lot.

But as said - maybe just my problem coming form another language.

Thanks for your help!!!

If you want, you can explicitly specify the type parameter, T, using turbofish syntax. It's just that people normally don't bother because it can be inferred from context, and because of the strong type system with no overloads or implicit conversions, you can normally be pretty sure the compiler isn't doing something funny behind your back.

let (sender, receiver) = mpsc::channel::<u32>();

(this isn't specific to channels, in general whenever you see a type parameter you can specify it using that syntax)

1 Like

To answer this kind of question, “IDE”s like rust-analyzer can be super useful. If you have code like

use std::sync::mpsc;

// just an example
pub struct UserData {
    pub guard1: bool,
}

pub struct Message<T> {
    pub ev: u8,
    pub some_data: T,
}

#[allow(unused)]
fn main() {
    let (tx, rx) = mpsc::channel();
    let mut msg = Message {ev: 0, some_data: true};
    tx.send(msg);
}

it can tell you type information in the tooltip

Screenshot_20220712_125537

and if you’re unsure what this “Sender” type is, there’s even a tooltip in the tooltip:

Screenshot_20220712_125559


Alternatively, in order to display inferred types without IDEs, it can help to utilize compiler error messages. You say you want to write a function that takes tx. So just write it with some wrong type like (), and see the result:

#![allow(unused)]

use std::sync::mpsc;

// just an example
pub struct UserData {
    pub guard1: bool,
}

pub struct Message<T> {
    pub ev: u8,
    pub some_data: T,
}

fn main() {
    let (tx, rx) = mpsc::channel();
    let mut msg = Message {ev: 0, some_data: true};
    tx.send(msg);
    take_tx(tx);
}

fn take_tx(tx: ()) {}
error[E0308]: mismatched types
  --> src/main.rs:19:13
   |
19 |     take_tx(tx);
   |     ------- ^^ expected `()`, found struct `Sender`
   |     |
   |     arguments to this function are incorrect
   |
   = note: expected unit type `()`
                 found struct `Sender<Message<bool>>`
note: function defined here
  --> src/main.rs:22:4
   |
22 | fn take_tx(tx: ()) {}
   |    ^^^^^^^ ------

notice how it tells you that tx is a Sender<Message<bool>>. A similar approach is to instead of calling a function, just assign a variable

let _: () = tx;
error[E0308]: mismatched types
  --> src/main.rs:19:17
   |
19 |     let _: () = tx;
   |            --   ^^ expected `()`, found struct `Sender`
   |            |
   |            expected due to this
   |
   = note: expected unit type `()`
                 found struct `Sender<Message<bool>>`
1 Like