这为什么编译通过?

huangapple go评论72阅读模式
英文:

Why this compiles?

问题

我尝试编译一个包含这个函数的程序,我原以为它不会通过编译器,但事实证明它通过了,并且我想知道为什么。

我目前正在学习Rust,最近遇到了这个函数:

fn test(input_str: &str) -> &str {
    if input_str == "" {
        let default: &str = "default";
        &default
    } else {
        input_str
    }
}

据我所知,我们不能返回对函数内分配的变量的引用,因为它的生命周期不够长。但我尝试编译这个函数,结果竟然成功通过编译。我想知道为什么会这样,我的理论是硬编码的字符串在某种程度上被处理得不同,以某种方式可以生存得和主程序一样长。但我不知道为什么会这样。所以请有人清楚地解释一下:)谢谢。

英文:

I've tried to compile a program that contains this function, I was expecting it to not pass the compiler but it turns out it does and I'd like to know why so.

I'm currently learning Rust and recently I've encountered this function

fn test(input_str: &str) -> &str {
    if input_str == "" {
        let default: &str = "default";
        &default
    } else {
        input_str
    }
}

and as far as I know, we cannot return a reference to a variable allocated in the function as it does not live long enough, and I've tried to compile this function and it turns out that it passes the compilation successfully, I'd like to know why it does, my theory is that a hardcoded strings are treated somewhat differently and somehow they live as long as the main program but I don't know WHY so. So please can someone explain it to me clearly : ) and thnx.

答案1

得分: 3

以下是翻译好的部分:

关键在于 &quot;default&quot; 不是 "variable allocated"<sup>1</sup>,它是一个静态字符串,或者在Rust中称为 &amp;&#39;static str。这是因为引号括起来的字符串在代码编译时实际上已经被"烘焙"进去了,它们是零成本且始终存在的。这个函数中没有任何需要分配<sup>2</sup>的内容。

返回它没有问题。但对于 &amp;String 就不能这样说。它们需要分配,这会使它们的处理变得复杂。

话虽如此,你可以返回一个明确为 static 版本的字符串的引用,但这需要更多的准备工作,而且需要像 once_celllazy_static 这样的工具。

--

<sup>1</sup> 这实际上并不是一回事。变量并不分配,但它们可以"拥有"已分配的东西。

<sup>2</sup> 这里的意思是"动态分配",与栈空间预留相对。

英文:

The key here is that &quot;default&quot; is not "variable allocated"<sup>1</sup>, it's a static string, or &amp;&#39;static str in Rust parlance. This is because quoted strings are effectively "baked in" when your code is compiled, they're zero cost and always present. Nothing in this function requires allocation<sup>2</sup>.

There's no problem returning that. The same could not be said for &amp;String. Those need allocations that complicate their handling.

That being said, you could return a reference to an explicitly static version of a String, but this requires a bit more preparation, not to mention tools like once_cell or lazy_static.

--

<sup>1</sup> This is not really a thing. Variables don't allocate, but they can "own" something that is allocated.

<sup>2</sup> Here meaning "dynamic allocation" as opposed to, say, stack space reservations.

huangapple
  • 本文由 发表于 2023年5月21日 07:31:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297727.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定