当参数作为引用传入时,为什么泛型函数需要 Copy 特性?

问题描述 投票:0回答:1

我的主要编程语言是 Java,我刚刚开始接触 C/C++ 和 Rust 等低级语言。因为 Java 有一个垃圾收集器,所以我从来不用担心内存管理。进入 C/C++ 和 Rust 让我意识到我对指针、引用等知之甚少

如果我有一个简单的通用函数,例如:

fn get_average <T> (x: &T, y: &T) -> T
    where T: Add<Output = T> + Div<Output = T> + From<u8>
{
    (*x + *y) / T::from(2)
}

编译器会输出如下内容:

error[E0507]: cannot move out of `*x` which is behind a shared reference
  --> src\main.rs:12:6
   |
12 |     (*x + *y) / T::from(2)
   |     -^^------
   |     ||
   |     |move occurs because `*x` has type `T`, which does not implement the `Copy` trait
   |     `*x` moved due to usage in operator
   |
note: calling this operator moves the left-hand side

error[E0507]: cannot move out of `*y` which is behind a shared reference
  --> src\main.rs:12:11
   |
12 |     (*x + *y) / T::from(2)
   |           ^^ move occurs because `*y` has type `T`, which does not implement the `Copy` trait

当我传入 x 和 y 作为引用时,为什么 T 需要“复制”特性?非常感谢任何帮助!

function generics rust add division
1个回答
0
投票

当你通过引用传递一个变量(在 Rust 中)时,你是在借用它,这意味着你不拥有数据,你不能将它移出引用。在您的代码中,您试图通过使用 * 运算符取消引用来将值移出引用。

一个解决方案是您可以更改函数签名以接受可变引用而不是共享引用。然后您可以在函数内部修改 x 和 y 的值,因为 * 运算符可用。

游乐场

use std::ops::{Add, Div};

fn get_average<T>(x: &T, y: &T) -> T
    where T: Add<Output = T> + Div<Output = T> + From<u8> + Copy
{
    (*x + *y) / T::from(2)
}

fn main() {
    let x = 420;
    let y = 69;
    let avg = get_average(&x, &y);
    println!("The average of {} and {} is {}", x, y, avg);
}

这里我们使用 Copy trait 来表示可以通过简单地复制内存中的位来复制类型,而无需任何深度复制。

© www.soinside.com 2019 - 2024. All rights reserved.