rust - 无论如何都隐式转换为静态生存期::错误

标签 rust reference

我正在Rust中读取anyhow crate 的代码。我不完全了解particular line:

{
 let vtable = &ErrorVTable { ... };
 construct(vtable, ...);
}

fn construct(vtable: &'static ErrorVTable, ...);
我们似乎创建了一个ErrorVTable结构,并返回对其具有生命周期`static的引用。我希望编译器在函数堆栈上创建一个结构,并返回对其的引用,从而导致奇怪的内存问题。
但是似乎编译器检测到在编译时推断出的所有可能的E的此变量,并以某种方式为它们创建了静态变量?这实际上如何运作?

最佳答案

考虑以下简化代码:

struct Foo {
    x: i32
}

fn test(_: &'static Foo) {}

fn main() {
    let f = Foo{ x: 42 };
    test(&f);
}
如预期的那样,它不会与以下消息一起编译:

f does not live long enough


但是,这种稍微的变化确实可以编译:
fn main() {
    let f = &Foo{ x: 42 };
    test(f);
}
区别在于,在前者中,Foo对象是本地的,具有本地生存期,因此无法构建'static引用。但是在后者中,实际对象是静态常量,因此具有静态生存期,并且f只是对其的引用。
为了帮助您了解两者之间的区别,请考虑以下其他等效代码:
const F: Foo = Foo{ x: 42 };
fn main() {
    test(&F);
}
或者,如果您使用实际的常量文字:
fn test_2(_: &'static i32) {}
fn main() {
    let i = &42;
    test_2(&i);
}
自然,这仅在Foo构造的所有参数都恒定的情况下才有效。如果任何值不是常数,则编译器将静默切换到本地临时变量而不是静态常数,并且您将失去'static生存期。
有时会称为constant promotion的确切规则有些复杂,可能会在较新的编译器版本中进行扩展。

关于rust - 无论如何都隐式转换为静态生存期::错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63300111/

相关文章:

c# - 等效于 http ://www. cplusplus.com/for C# .net

linux - bash中间接引用数组的访问范围

java - Java 中引用的表示

c++ - "Undefined reference to"使用 Lua

rust - 当其中一个字符串似乎超出范围时,为什么这段带有字符串文字的代码会编译?

rust - 我如何接受同一个 Serde 字段的多个反序列化名称?

random - 在偏向中间的范围内生成随机无符号整数

arrays - 来自范围的常量数组

rust - 在构建脚本中获取当前版本的方法?

c++ - 右值引用