首页 > 其他分享 >文盘Rust -- struct 中的生命周期

文盘Rust -- struct 中的生命周期

时间:2022-10-08 11:22:26浏览次数:65  
标签:mut struct -- self say Base Rust String

最近在用rust 写一个redis的数据校验工具。redis-rs中具备 redis::ConnectionLike trait,借助它可以较好的来抽象校验过程。在开发中,不免要定义struct 中的某些元素为 trait object,从而带来一些rust语言中的生命周期问题。
本文不具体讨论 redis的数据校验过程,通过一个简单的例子来聊聊 struct 中 trait object 元素的生命周期问题。

首先来定义一个 base trait,该 trait 中只包含一个函数,返回String类型。

pub trait Base {
    fn say(&self) -> String;
}

接下来,定义两个实现了 Base trait 的 struct AFromBase 和 BFromBase

pub struct AFromBase {
    content: String,
}

impl Base for AFromBase {
    fn say(&self) -> String {
        self.content.clone()
    }
}

pub struct BFromBase {
    text: String,
}

impl Base for BFromBase {
    fn say(&self) -> String {
        self.text.clone()
    }
}

接下来,定义一个struct 包含两个 Base trait 的 trait object ,然后实现一个函数是 say 函数输出的字符串的拼接结果.
按照其他没有生命周期语言的编写习惯,直觉上这么写

pub struct AddTowBase {
    a: &mut dyn Base,
    b: &mut dyn Base,
}

impl AddTowBase {
    fn add(&self) -> String {
        let result = self.a.say() + &self.b.say();
        result
    }
}

最后,搞个main函数验证一下。
完整代码如下

pub trait Base {
    fn say(&self) -> String;
}

pub struct AFromBase {
    content: String,
}

impl Base for AFromBase {
    fn say(&self) -> String {
        self.content.clone()
    }
}

pub struct BFromBase {
    text: String,
}

impl Base for BFromBase {
    fn say(&self) -> String {
        self.text.clone()
    }
}

pub struct AddTowBase {
    a: &mut dyn Base,
    b: &mut dyn Base,
}

impl<'a> AddTowBase<'a> {
    fn add(&self) -> String {
        let result = self.a.say() + &self.b.say();
        result
    }
}

fn main() {
    let mut a = AFromBase {
        content: "baseA".to_string(),
    };

    let mut b = BFromBase {
        text: "baseB".to_string(),
    };

    let addtow = AddTowBase {
        a: &mut a,
        b: &mut b,
    };
    let r = addtow.add();
    println!("{}", r);
}

很遗憾,以上代码是不能编译通过的,编译时报如下错误

error[E0106]: missing lifetime specifier
  --> examples/lifetimeinstruct.rs:26:8
   |
26 |     a: &mut dyn Base,
   |        ^ expected named lifetime parameter
   |
help: consider introducing a named lifetime parameter
   |
25 ~ pub struct AddTowBase<'a> {
26 ~     a: &'a mut dyn Base,
   |

error[E0106]: missing lifetime specifier
  --> examples/lifetimeinstruct.rs:27:8
   |
27 |     b: &mut dyn Base,
   |        ^ expected named lifetime parameter
   |
help: consider introducing a named lifetime parameter
   |
25 ~ pub struct AddTowBase<'a> {
26 |     a: &mut dyn Base,
27 ~     b: &'a mut dyn Base,
   |

For more information about this error, try `rustc --explain E0106`.
error: could not compile `wenpan-rust` due to 2 previous errors

编译器给出的提示很明确,要在 trait object 上添加生命周期参数,确保 struct 和他的 trait object 元素在同一生命周期,避免悬垂指针。
我们按照编译器的提示修改代码

pub struct AddTowBase<'a> {
    a: &'a mut dyn Base,
    b: &'a mut dyn Base,
}

impl<'a> AddTowBase<'a> {
    fn add(self) -> String {
        let result = self.a.say() + &self.b.say();
        result
    }
}

代码顺利通过编译。
rust 的生命周期保证了内存的安全性,同时也增加了开发者的心智负担。是在上线之前多费心思写代码,还是在上线以后忙忙活活查问题,这是个 trade off 问题。俗话讲:"背着抱着,一样沉".我本人还是倾向于把问题控制在上线之前,少折腾用户。

本期咱们先聊到这儿,下期见

标签:mut,struct,--,self,say,Base,Rust,String
From: https://www.cnblogs.com/Jcloud/p/16768365.html

相关文章

  • MUR1100-ASEMI轴向快恢复二极管MUR1100
    编辑:llMUR1100-ASEMI轴向快恢复二极管MUR1100型号:MUR1100品牌:ASEMI封装:DO-41特性:快恢复二极管正向电流:1A反向耐压:1000V恢复时间:50ns引脚数量:2芯片个数:1芯片尺寸......
  • 关于el-select做分页后切换分页显示id的问题
    刚刚用el-select做项目,数据很多使用了分页,然而当切换分页时,已选中的数据显示为id而不是name,这个地方需要增加romote属性,  还要注意,在加了clearable之后,我的可搜索功......
  • base64与中文字符串互转
    实现代码如下//字符串转base64getEncode64(str){returnbtoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,functiontoSolidBytes(match,p......
  • 带掩码的自编码器(MAE)最新的相关论文推荐
     1、HeterogeneousGraphMaskedAutoencodersYijunTian,KaiwenDong,ChunhuiZhang,ChuxuZhang,NiteshV.Chawlahttps://arxiv.org/pdf/2208.09957生......
  • Jenkins 20221007笔记本6
                ......
  • TypeScript介绍
    1. TypeScript是什么?TypeScript(简称:TS)是JavaScript的超集(JS有的TS都有)TypeScript=Type+JavaScript(在JS基础之上,为JS添加了类型支持)......
  • (九)模仿学习-动态更改大屏数据
    我们通过前面的练习,完全可以完成一个返回页面的操作。首先我们准备一个action并在struts.xml中添加。创建action我们先什么数据都不返回,只返回一个页面在application......
  • 真心祝福你 歌谱
    真心祝福你歌谱真心祝福你 以我们主的圣名真心祝福你 以我们主的大爱在这里聚集 所有主的圣洁儿女愿主的喜乐 主的大爱充满这里 充满这里我们之中神爱你 祝......
  • E. Explorer
    Explorer题目大意给定一个n个点m条边的无向图。每个边拥有四个属性,u,v,l,r分别表示为连接u,v两点的一条边,其只能通过体型在[l,r]的人。问从1到n有多少体型可以通过。分......
  • 2022.10.8
    关于我电脑坏了:隔了好久没有写东西主要原因是电脑坏了电脑店老板给人感觉挺不错的,说自己也是网络工程,但是那个时候有学硬件方向他给我看了电脑,说是主板问题,他修不了,可......