How do you create a generic function in Rust with a trait requiring a lifetime?

混江龙づ霸主 提交于 2019-12-01 06:25:39
Shepmaster

You have defined Storable with a generic parameter, in this case a lifetime. That means that the generic parameter has to be propagated throughout the entire application:

fn put<'de, S: Storable<'de>>(obj: &'de S) -> Result<(), String> { /* ... */ }

You can also decide to make the generic specific. That can be done with a concrete type or lifetime (e.g. 'static), or by putting it behind a trait object.

Serde also has a comprehensive page about deserializer lifetimes. It mentions that you can choose to use DeserializeOwned as well.

trait Storable: Serialize + DeserializeOwned { /* ... */ }

You can use the same concept as DeserializeOwned for your own trait as well:

trait StorableOwned: for<'de> Storable<'de> { }

fn put<'de, S: StorableOwned>(obj: &'de S) -> Result<(), String> {

You have the 'de lifetime in the wrong place -- you need it to specify the argument to Storable, not the lifetime of the reference obj.

Instead of

fn to_json<'de, S: Storable>(obj: &'de S) -> String {

use

fn to_json<'de, S: Storable<'de>>(obj: &S) -> String {

Playground.

The lifetime of obj doesn't actually matter here, because you're not returning any values derived from it. All you need to prove is that S implements Storable<'de> for some lifetime 'de.

If you want to eliminate the 'de altogether, you should use DeserializeOwned, as the other answer describes.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!