繁体   English   中英

即使数组包含也具有静态生命周期的值,也无法返回对临时数组的静态引用

[英]Cannot return a static reference to a temporary array even when the array contains a value that also has the static lifetime

T::bar返回的值具有'static生命周期,因此Test2::foo范围不需要拥有任何东西。 &[T::bar()]作为&'static [&'static StructType]应该是安全的吗? Test:foo编译没有问题,所以我期待Test2::foo能编译。

代码

pub struct StructType {
    a: &'static str,
}

pub trait Foo {
    fn foo() -> &'static [&'static StructType];
    fn bar() -> &'static StructType;
}

pub struct Test;

impl Foo for Test {
    fn foo() -> &'static [&'static StructType] {
        &[&StructType { a: "asdf" }]
    }

    fn bar() -> &'static StructType {
        &StructType { a: "asdf" }
    }
}

pub struct Test2<T: Foo>(T);

impl<T: Foo> Test2<T> {
    pub fn foo() -> &'static [&'static StructType] {
        &[T::bar()]
    }
}

操场

错误

error[E0515]: cannot return reference to temporary value
  --> src/lib.rs:26:9
   |
26 |         &[T::bar()]
   |         ^----------
   |         ||
   |         |temporary value created here
   |         returns a reference to data owned by the current function

RFC 将值的引用自动提升为'static状态:

将 constexpr 右值提升为静态内存而不是堆栈槽中的值,并通过能够直接创建对它们的“静态引用”来公开语言中的值。

文字值是最明显的常量表达式。 但是,除非使用const明确标记为这样,否则函数调用不是const 然而,从 Rust 1.31 开始,用户定义的const函数中可用的操作类型相当有限。 允许使用文字值:

const fn bar() -> &'static StructType {
    &StructType("asdf")
}

const fn combo() -> &'static [&'static StructType; 1] {
    &[Self::bar()]
}

从基准转换为阵列,以切片中没有一个允许const功能又,使得需要在不同的功能:

fn wombo() -> &'static [&'static StructType] {
    Self::combo()
}

此外,您不能在特征中定义const函数。

也可以看看:

我真正需要的是 1) 让T::bar()返回一个常量,2) 让Test:foo返回一个数组常量,它是由T::bar()U::bar()U构造的, TTest通用参数

你不可以做这个

fn example<T>() {
    static NO_CAN_DO: T = unimplemented!();
}
error[E0401]: can't use type parameters from outer function
 --> src/lib.rs:2:23
  |
1 | fn example<T>() {
  |    ------- - type variable from outer function
  |    |
  |    try adding a local type parameter in this method instead
2 |     static NO_CAN_DO: T = unimplemented!();
  |                       ^ use of type variable from outer function

也可以看看:

我认为你在以错误的方式思考生命。 似乎您使用它们来“声明”您希望它存活多长时间,但您无法更改引用的生命周期。 生命周期说明符所做的所有事情都是帮助编译器在没有信息来省略它的情况下理解生命周期。

第 15.4.7 章来自 Rust 的静态实例应该能帮到你。

基本上,只有两种方法可以创建'static数据”:

  1. 使用static声明创建一个常量。
  2. 制作一个字符串文字,其类型为: &'static str

您可以通过像在 Rust 中通常所做的那样声明生命周期说明符来实现与上述相同的效果(但编译器建议使用'static生命周期”,因为您自己没有声明任何生命周期)。 见下文。

主要的一点是,除了&'static str ,永远不能通过在函数中注释生命周期来改变生命周期。 当你写&[T::bar()] ,数组不是一个常量,如果你的函数离开作用域就会被删除。 如果您希望它具有'static生命周期”,则需要使其成为如下所示的常量。

现在这可能不是你想要做的,但它会编译,我希望解释不同之处:

const ARR: &'static [&'static StructType] = &[&StructType { a: "asdf" }];

pub struct StructType {
    a: &'static str,
}

pub trait Foo<'a> {
    fn foo() -> &'a [&'a StructType];
    fn bar() -> &'a StructType;
}

pub struct Test;

impl<'a> Foo<'a> for Test {
    fn foo() -> &'a [&'a StructType] {
        &[&StructType { a: "asdf" }]
    }

    fn bar() -> &'a StructType {
        &StructType { a: "asdf" }
    }
}

pub struct Test2<T: Foo<'static>>(T);

impl<T: Foo<'static>> Test2<T> {
    pub fn foo() -> &'static [&'static StructType] {
        ARR
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM