Rust 为什么在浮点数阵列上调用iter会给出;临时值被释放";使用f64::from_位时?

Rust 为什么在浮点数阵列上调用iter会给出;临时值被释放";使用f64::from_位时?,rust,copy,lifetime,drop,Rust,Copy,Lifetime,Drop,我遇到了一个终生错误,我无法解释为什么编译器会发出这个错误。我需要这个(很好用): fn-iter{ [3.14].国际热核实验堆() } 但是,当我尝试使用从特定字节表示转换而来的浮点值时,如下所示: fn-iter{ [f64::from_位(0x7fffffffffffffff)].iter() } 它给了我“创建一个在使用中被释放的临时文件”。操场(马厩1.45.2) 我的推理是,由于f64是Copy类型(如果我使用常量值,它确实可以像预期的那样工作),因此应该可以工作,因为不应该对

我遇到了一个终生错误,我无法解释为什么编译器会发出这个错误。我需要这个(很好用):

fn-iter{
[3.14].国际热核实验堆()
}
但是,当我尝试使用从特定字节表示转换而来的浮点值时,如下所示:

fn-iter{
[f64::from_位(0x7fffffffffffffff)].iter()
}
它给了我“创建一个在使用中被释放的临时文件”。操场(马厩1.45.2)

我的推理是,由于
f64
Copy
类型(如果我使用常量值,它确实可以像预期的那样工作),因此应该可以工作,因为不应该对该值执行释放

所以问题是为什么编译器在第二种情况下发出错误

谢谢你的指点和解释


另外,我需要引用上的迭代器,因为它非常适合我的其他API。

您的代码有两个相关问题:

  • 返回对临时对象的引用,该对象超出函数体末尾的范围
  • 返回类型包含未绑定到任何函数输入的生存期参数
  • 引用只能在其指向的数据存在的时间内存在。方法调用的结果
    f64::from_bits(0x7fffffffffffffffff)
    是一个临时对象,在表达式末尾超出范围。从函数返回对临时值或局部变量的引用是不可能的,因为一旦函数返回,引用的值将不再有效

    Copy
    特性,或者对象是否存储在堆上,与超出范围的值不能再被引用这一事实完全无关。函数中创建的任何值都将超出函数体末尾的范围,除非通过返回值将其移出函数。然而,您需要移动该值的所有权才能使其生效——您不能简单地返回引用

    由于不能返回对函数内创建的任何值的引用,因此返回值中的任何引用都必须引用通过函数参数传入的内容。这意味着返回值中任何引用的生存期都需要与传递给函数的某个引用的生存期相匹配。这就引出了第二点——仅在返回类型中出现的生存期参数始终是一个错误。生命周期参数是由调用代码选择的,因此您的基本意思是,您的函数返回一个在调用方选择的任意时间内存在的引用,这只有在引用引用的静态数据与程序存在的时间一样长时才可能

    这也解释了为什么第一个示例有效。文本
    [3.14]
    定义了一个常量静态数组。这个数组将和程序一样长,因此您可以返回具有任意生存期的引用。但是,您通常会通过显式指定静态生存期来表达这一点,以明确发生了什么:

    fn iter() -> impl Iterator<Item = &'static f64> {
        [3.14].iter()
    }
    

    fn iter()->impl迭代器您的代码有两个相关问题:

  • 返回对临时对象的引用,该对象超出函数体末尾的范围
  • 返回类型包含未绑定到任何函数输入的生存期参数
  • 引用只能在其指向的数据存在的时间内存在。方法调用的结果
    f64::from_bits(0x7fffffffffffffffff)
    是一个临时对象,在表达式末尾超出范围。从函数返回对临时值或局部变量的引用是不可能的,因为一旦函数返回,引用的值将不再有效

    Copy
    特性,或者对象是否存储在堆上,与超出范围的值不能再被引用这一事实完全无关。函数中创建的任何值都将超出函数体末尾的范围,除非通过返回值将其移出函数。然而,您需要移动该值的所有权才能使其生效——您不能简单地返回引用

    由于不能返回对函数内创建的任何值的引用,因此返回值中的任何引用都必须引用通过函数参数传入的内容。这意味着返回值中任何引用的生存期都需要与传递给函数的某个引用的生存期相匹配。这就引出了第二点——仅在返回类型中出现的生存期参数始终是一个错误。生命周期参数是由调用代码选择的,因此您的基本意思是,您的函数返回一个在调用方选择的任意时间内存在的引用,这只有在引用引用的静态数据与程序存在的时间一样长时才可能

    这也解释了为什么第一个示例有效。文本
    [3.14]
    定义了一个常量静态数组。这个数组将和程序一样长,因此您可以返回具有任意生存期的引用。但是,您通常会通过显式指定静态生存期来表达这一点,以明确发生了什么:

    fn iter() -> impl Iterator<Item = &'static f64> {
        [3.14].iter()
    }
    

    fn iter()->impl Iterator它是
    Copy
    ,它在语义上是被复制的,这确实是问题所在,因为它在语义上只存在于堆栈上,直到函数返回,引用现在在语义上指向堆栈外的内存,并且很可能很快被覆盖,如果允许的话,这将导致未定义的行为

    除此之外,
    from_bits
    不是const,这意味着您无法在编译时转换静态值,这是一个运行时操作。既然已经知道值,为什么每次都要转换?