思考题 day 2
本文最后更新于 117 天前,其中的信息可能已经有所发展或是发生改变。

原题

实现一个签名函数to_static_str让它的返回值生命周期为 ‘static

fn to_static_str(s:String)->&'static str {

}
fn main {
    let s = "xxx";
    let s1 = to_static_str(s.clone);
    assert(s==s1);
}

分析

首先,看到题目第一眼,我想到了《圣经》中的一段代码示例

fn dangle() -> &String { // dangle 返回一个字符串的引用

    let s = String::from("hello"); // s 是一个新字符串

    &s // 返回字符串 s 的引用
} // 这里 s 离开作用域并被丢弃。其内存被释放。
  // 危险!

这是一段悬垂引用的示例,这里正常返回了借用的s,但是s在函数结束时已经被释放了,如果我们直接返回s,就可以正常返回 然后我们结合题目,如果我们返回s,那他的生命周期为`a,这不符合我们的需求

这里我们剖析一下我们的需求,首先就是我们需要生命周期为`static的返回值,这意味着这个返回值的所有权不能移交给别人,那我们就需要让上文的悬垂引用实现,接下来我们的问题是当我们 &s,它已经被释放了,等等,写到这里,我突然想到了发散函数,如果我们在发散函数中借用了s,是否意味着s的生命周期发生改变?让我们试试

fn forever(s2:String) -> !{
    loop {
        &s2;
    };
}
fn to_static_str(s:String)->&'static str {
    forever(s);
    &s
}
fn main() {
    let s = "xxx";
    let s1 = s.clone();
    let s2 = to_static_str(s1.to_string());
    assert_eq!(s,s1);
}

总结

结果是这个代码报了一堆warning然后应该是编译不出来,我还是再多学学再研究这个吧

评论

  1. Avatar photo
    gtchases
    博主
    4 月前
    2025-9-19 5:00:23

    @ling 坑爹,超纲了

  2. Avatar photo
    博主
    4 月前
    2025-9-19 12:11:09

    这段代码当然编译不出来,forever需要的是String类型,它会拿走变量的所有权,forever(s)之后,s已经失效了,你再&s,这不是悬垂引用了?
    而且forever不会返回,在forever调用后面的代码根本没有机会执行。
    另外,其他模块持有引用,并不会改变引用的生命周期,Rust只会要求你必须保证引用的生命周期足够长,而不会在运行时改变它。

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇