I designed a function for this object to set the message that needs to be sent when MQTT data is received:
#[must_use]
pub fn set_message_callback<S>(self, msg: S) -> Self
where
S: Fn(mqtt::Message) -> T + 'static,
{
let tx = self.tx.clone();
self.client.set_message_callback(move |_cli, data| {
if let Some(v) = data {
tx.send(msg(v)).expect("Failed to Send Mqtt Data");
}
});
self
}
I call this function in another thread like this:
enum AppMessage {
MqttMessage(paho_mqtt::Message),
}
let mqtt_client = AsyncMqttClient::new(tx.clone())
.set_message_callback(AppMessage::MqttMessage)
Here is the question: in this function, the āmsgā object will return a static object. Does this mean that every time MQTT receives a message, it will generate a static variable? Will this eventually lead to a memory leak?
No. A : 'staticbound on a type does not mean that the value is alive for the 'static lifetime. It means that the value isn't allowed to contain any temporary (i.e., shorter than 'static) references; in practice, this usually (but not necessarily) implies that the value is an owning value and contains no references at all.
Lifetime annotations don't influence the lifetime of any value anyway; they are only checked against the relevant bindings (i.e., they are constraints, not "commands"). Only owning bindings keep values alive.
In general, it's hard to leak memory by accident in Rust. The language is designed to do the right thing by default. As long as you restrict your data model to a tree-structured ownership scheme (i.e., no cycles using Rc or Arc), and do not use rarely-needed advanced memory management primitives (e.g. interior mutability) or explicitly leak memory (using e.g. mem::forget() or Box::leak()), leaks will be obvious for the most part.
It means S will return a valueļ¼It could be a value with a static lifetime or an owned type value. In this code, it will return an āAppMessageā, which will be droped after exiting the code.
Thanks! This is very helpful for understanding the life time.
Note that the + puts together multiple bounds; it isn't part of the syntax of the Fn trait and does not apply to the return value.
where
S: Fn(mqtt::Message) -> T + 'static,
means exactly the same as
where
S: Fn(mqtt::Message) -> T,
S: 'static,
and if you wanted to constrain T then you would have to write T: 'static instead. That is, the above is saying that the function of type S must not have any short-lived borrows in it.
Oh, it seems there is still mistake in my previous understanding. It means type āSā must have 'static bound; I've checked the code of paho-mqtt, the closure of "set_message_callback" is defined as 'static: