< 返回版块

ankoGo 发表于 2024-03-18 08:50

struct InnerA {}

struct InnerB<'a> {
    inner_a: &'a InnerA,
}

struct Outer<'b> {
    inner_a: InnerA,
    inner_b: InnerB<'b>,
}

fn main() {
    let inner_a = InnerA {};
    let inner_b = InnerB {
        inner_a: &inner_a,
    };
    let outer = Outer {
        inner_a: InnerA {},
        inner_b,
    };
    println!("OK");
}

如上代码,为什么Outer.inner_b也要标注生命周期?inner_b: InnerB并非引用,有懂王吗?多谢啦

评论区

写评论
北海 2024-03-22 14:40

要编译器自动化,可太难为编译器了,举个最简单的例子

// x和y的生命周期不一样,有时候调用max,x大于y的生命周期,有时候y大于x
// 编译器如何懂?编译器可以给x、y给分配一个生命周期,可返回值让编译器选择哪个?
fn max(x: &i32, y: &i32) -> &i32 {
    if *x > *y { x } else { y }
} 

另外,struct Outer<'b, 'c, 'd, 'e>,如果没有必要,选取一个最小的就行,struct Outer<'a>就行。'b、'c、'd、'e既然是类型,他们是有子类型之分的,生命周期长的是生命周期短的子类型,子类型可以代替父型。当然,如果非要分的清楚,那时候的确需要每个都要单独写。

// 很多时候,这种一个最短的生命周期的,就足够了
struct Outer<'a> {
    a: A,
    b: B<'a>,
    c: C<'a>,
    d: D<'a>,
    e: E<'a>,
}

你要不说套娃,多个变量的,谁能一开始理解你的意思呢?好像,我之前就知道你要问这种多个的一样,怪我喽。另外,抱歉,我确实职场待久了,不是一个随便的人,想高质量讨论,希望大家相互尊敬。敏感的人还有很多,建议你还是注意,这个社会上不会说话,得罪同事、客户的你连知道都不知道。先评判人咋样咋样的即没啥礼貌一般也不会多有水平,就事论事不就是只论事不论人。当然,如果你行你素,觉得人家太敏感,那我也无所谓的,我只要避而远之就好。

作者 ankoGo 2024-03-22 12:52

套娃还只是按照一个字段来说的,在实战中,多个字段都是引用的情况下呢?所以嘛,我问的是是否有简单的编译器自动推断生命周期出来,而不用显式标注,比如下面的代码就特别麻烦:(注意下面例子只是刚好都是在main里面创建的实例对象,但是在实战中,一般都是每个字段都有不同的生命周期,所以,下面是必须struct Outer<'b,'c,'d,'e>,而不是struct Outer<'o>{}且所有字段都采用同一生命周期标注'o)

struct A {}

struct B<'b> {
    b_a: &'b A,
}

struct C<'c> {
    c_a: &'c A,
}

struct D<'d> {
    d_a: &'d A,
}

struct E<'e> {
    e_a: &'e A,
}


struct Outer<'b,'c,'d,'e> {
    a: A,
    b: B<'b>,
    c: C<'c>,
    d: D<'d>,
    e: E<'e>,
}

fn main() {
    let a = A {};
    let b = B {
        b_a: &a,
    };

    let c = C {
        c_a: &a,
    };
    let d = D {
        d_a: &a,
    };
    let e = E {
        e_a: &a,
    };

    let outer = Outer {
        a: A {},
        b: b,
        c,
        d,
        e,
    };
    println!("OK");
}

作者 ankoGo 2024-03-22 12:47

我的意思是:如果这个层级比较多,比如上面的只是B里面嵌入A,只因为A带有引用,所以B就必须带有一个显式生命周期的标注,那假设在实战中,嵌套5-6层的类型,假设关系如下:G>F>E>d>C>B>A,然后岂不是因为A带有引用,导致嵌入A类型作为字段属性的类型都要显式生命周期标注出来?那真的是几乎生命周期无处不在,也几乎都要显式标注出来,真的特别麻烦

作者 ankoGo 2024-03-22 12:35

你说的我明白了,我也是这么理解的!只是不明白为什么要显式的标注这个生命周期出来,而不是编译器自己推断。。。 “懂王”是调侃的语气,我的天,你是不是心理太脆弱了点?

--
👇
北海: 所谓InnerB<'a>,为何带生命周期,先要知道'a也是一种泛型,这是在告诉你,InnerB里面包含一个'a生命周期的东西,所以inner_b: InnerB<'a>这个变量存活的长度可以超过其内部'a生命周期的东西不?inner_b: InnerB<'a>虽然是结构体,尽管有所有权转移,但其转移范围依然受限。倘若inner_b所有权转移跑出了'a生命周期范围外,inner_b就是危险的。

兄弟,你这“懂王”称号是形容川大将军的,姑且不论你提问说的是什么感情色彩。你上来就先判定别人懂不懂,说话的语气,评论区给人的感觉,就很难让人再回复你的问题。我劝你先别借评价他人这种手段来表达你的观点,因为你也不知道别人是什么水平!

--
👇
AnkoGo123: 没明白你的意思,可否展开说说?

--
👇
北海: 不懂就谦虚点啊,唉,最怕这种不懂,还以为自己很厉害的懂了的

北海 2024-03-22 10:56

所谓InnerB<'a>,为何带生命周期,先要知道'a也是一种泛型,这是在告诉你,InnerB里面包含一个'a生命周期的东西,所以inner_b: InnerB<'a>这个变量存活的长度可以超过其内部'a生命周期的东西不?inner_b: InnerB<'a>虽然是结构体,尽管有所有权转移,但其转移范围依然受限。倘若inner_b所有权转移跑出了'a生命周期范围外,inner_b就是危险的。

兄弟,你这“懂王”称号是形容川大将军的,姑且不论你提问说的是什么感情色彩。你上来就先判定别人懂不懂,说话的语气,评论区给人的感觉,就很难让人再回复你的问题。我劝你先别借评价他人这种手段来表达你的观点,因为你也不知道别人是什么水平!

--
👇
AnkoGo123: 没明白你的意思,可否展开说说?

--
👇
北海: 不懂就谦虚点啊,唉,最怕这种不懂,还以为自己很厉害的懂了的

作者 ankoGo 2024-03-22 10:35

没明白你的意思,可否展开说说?

--
👇
北海: 不懂就谦虚点啊,唉,最怕这种不懂,还以为自己很厉害的懂了的

北海 2024-03-21 10:10

不懂就谦虚点啊,唉,最怕这种不懂,还以为自己很厉害的懂了的

作者 ankoGo 2024-03-20 11:43

好的,感谢各位大佬不吝赐教

Bai-Jinlin 2024-03-20 10:37

写结构不能省略,剩下函数签名,引用类型变量什么的都可以省略

--
👇
asuper: 是这样的啊,我们平时写的代码,只要出现了 &,都是引用,有个隐含的生命周期标记的,编译器帮你处理了而已

--
👇
AnkoGo123: 那照你这样说,几乎都是引用,引用几乎无处不在。。。也就是生命周期几乎无处不在

--
👇
asuper: InnerB内部元素 inner_a: &'a InnerA, 是一个引用,那也就相当于 inner_b: InnerB<'b>, 是引用,引用,都是指向其他变量的,生产周期依赖于他所引用的对象。 类似的可以参考Option的as_ref()

asuper 2024-03-20 09:44

是这样的啊,我们平时写的代码,只要出现了 &,都是引用,有个隐含的生命周期标记的,编译器帮你处理了而已

--
👇
AnkoGo123: 那照你这样说,几乎都是引用,引用几乎无处不在。。。也就是生命周期几乎无处不在

--
👇
asuper: InnerB内部元素 inner_a: &'a InnerA, 是一个引用,那也就相当于 inner_b: InnerB<'b>, 是引用,引用,都是指向其他变量的,生产周期依赖于他所引用的对象。 类似的可以参考Option的as_ref()

作者 ankoGo 2024-03-19 20:46

那照你这样说,几乎都是引用,引用几乎无处不在。。。也就是生命周期几乎无处不在

--
👇
asuper: InnerB内部元素 inner_a: &'a InnerA, 是一个引用,那也就相当于 inner_b: InnerB<'b>, 是引用,引用,都是指向其他变量的,生产周期依赖于他所引用的对象。 类似的可以参考Option的as_ref()

asuper 2024-03-19 09:25

InnerB内部元素 inner_a: &'a InnerA, 是一个引用,那也就相当于 inner_b: InnerB<'b>, 是引用,引用,都是指向其他变量的,生产周期依赖于他所引用的对象。 类似的可以参考Option的as_ref()

作者 ankoGo 2024-03-18 23:12

我看过这么多文章,但是都是简单的介绍生命周期,这种情况真的几乎网上没人教学,或者指点出为什么。。。所以,目前来说我还没看到满意的合理的解释,希望路过朋友或者大佬指点一二,敬上!

ZZG 2024-03-18 20:53

在定义InnerB时,写的是

struct InnerB<'a>

所以 'a 和常见的 T 一样,是个类型参数,所以当用到InnerB的时候,也需要指明 'a 。

就好比,每次使用 Vec 的时候,一定要写Vec指明类型,二者逻辑上是一样的

TinusgragLin 2024-03-18 13:33

我觉得就可以把 InnerB<'b> 看成一个引用,要不然它为什么要一个生命周期参数勒。

作者 ankoGo 2024-03-18 13:15

楼1啥意思?展开说说嘛?

LionHunterwomen 2024-03-18 11:20

InnerB不是需要注释吗

1 共 17 条评论, 1 页