< 返回版块

lithbitren 发表于 2023-03-31 23:10

Tags:lifetime,生命周期,ast,抽象语法树

一段rust代码,首先保证生成抽象语法树,不知道编译器内部是怎样实现的,总之暂时以https://carlkcarlk.github.io/rust-ast-explorer/为参考。

生成完AST以后,才会对代码进行一系列的检查。

比如变量及引用的使用检查,这个在算法上很好描述,定义的时候标记一个是否使用为false,遍历AST的时候找到对应的定义改成true,最后再检查遍历一遍定义对象,还是false的就给个警告。

再比如类型检查及推导,没有类型的先标记个None,然后在相关作用域内搜索是否定义过类型,或者在使用函数的时候有没有被动定义的情况,如果定义过就回溯标记类型为Some(type),如果最后检查还是None就编译失败,如果多次定义就检查是否有矛盾,算法上也就用到深搜或并查集相关的知识,多次解引用算是个容易忽略的点,但也不是太难。

所以,生命周期标记的检查算法是怎么描述?

比如这段代码肯定报错:

fn func(x: &str, y: &str) -> &str{
    if x.len() > y.len() {x} else {y}
}

然后编译器会提示你改成这样才能通过:

fn func<'a>(x: &'a str, y: &'a str) -> &'a str{
    if x.len() > y.len() {x} else {y}
}

但就连生命周期入门案例都不是太好描述,更别说复杂的结构体/闭包生命周期了,而且还得跟main函数里具体的调用挂钩,比如有些标记会存在约束定义<'a, 'b: 'a>,那么函数定义的时候是合法的,但调用的时候就有可能不合法了。

像rust圣经4.1.1. 深入生命周期,最后那个复杂的例子,也不知道算法上是怎么检查的。

struct Interface<'b, 'a: 'b> {
    manager: &'b mut Manager<'a>
}

impl<'b, 'a: 'b> Interface<'b, 'a> {
    pub fn noop(self) {
        println!("interface consumed");
    }
}

struct Manager<'a> {
    text: &'a str
}

struct List<'a> {
    manager: Manager<'a>,
}

impl<'a> List<'a> {
    pub fn get_interface<'b>(&'b mut self) -> Interface<'b, 'a>
    where 'a: 'b {
        Interface {
            manager: &mut self.manager
        }
    }
}

fn main() {

    let mut list = List {
        manager: Manager {
            text: "hello"
        }
    };

    list.get_interface().noop();

    println!("Interface should be dropped here and the borrow released");

    // 下面的调用可以通过,因为Interface的生命周期不需要跟list一样长
    use_list(&list);
}

fn use_list(list: &List) {
    println!("{}", list.manager.text);
}

错误代码是全标记为<'a>,正确范例是加上了约束,标记为<'b, 'a: 'b>,但书里没说的是'a'b之间的约束不标也可以,就单纯标<'a, 'b>也可以编译通过。

https://course.rs/advance/lifetime/advance.html

从rust圣经下面的评论来看,大家也都挺迷糊的,如果有个明确的算法的话,是否能够帮助rust学习者更好的理解生命周期。

关于生命周期的算法,在rust项目下找了下,也没找到对应的代码,不知道哪里可以看到相关的信息。

评论区

写评论
作者 lithbitren 2023-04-01 20:39

感谢指路,原来是这篇,得好好学习下

--
👇
HC97: RFC 2094中文翻译

--
👇
lithbitren: 具体是哪个rfc啊,找了带lifetime的rfc,感觉大多讲的还是原则性指导方法,就像圣经里的经文,不是那种可以机械化执行的东西。

--
👇
HC97: NLL的RFC里有描述,可以参考一下,不知道有没有更新过,但是大概的算法描述是有的。

类型 &'a T 隐含了 T: 'a 约束,好像早期的版本需要手动标明,现在已经不需要写了。

HC97 2023-04-01 20:13

RFC 2094中文翻译

--
👇
lithbitren: 具体是哪个rfc啊,找了带lifetime的rfc,感觉大多讲的还是原则性指导方法,就像圣经里的经文,不是那种可以机械化执行的东西。

--
👇
HC97: NLL的RFC里有描述,可以参考一下,不知道有没有更新过,但是大概的算法描述是有的。

类型 &'a T 隐含了 T: 'a 约束,好像早期的版本需要手动标明,现在已经不需要写了。

作者 lithbitren 2023-04-01 19:13

具体是哪个rfc啊,找了带lifetime的rfc,感觉大多讲的还是原则性指导方法,就像圣经里的经文,不是那种可以机械化执行的东西。

--
👇
HC97: NLL的RFC里有描述,可以参考一下,不知道有没有更新过,但是大概的算法描述是有的。

类型 &'a T 隐含了 T: 'a 约束,好像早期的版本需要手动标明,现在已经不需要写了。

HC97 2023-03-31 23:44

NLL的RFC里有描述,可以参考一下,不知道有没有更新过,但是大概的算法描述是有的。

类型 &'a T 隐含了 T: 'a 约束,好像早期的版本需要手动标明,现在已经不需要写了。

1 共 4 条评论, 1 页