< 返回版块

liangxiaowei 发表于 2020-06-01 23:13

大家好,我在看 the rust programming language 教程。看到用范型实现通用的比较大小函数,我有点不理解为什么需要加 Copy trait 才能通过编译。

在《10.2 trait 定义共享的行为》里面说的原因是:“改成使用泛型后,参数的类型有可能没有实现 Copy trait ,意味着我们可能不能将 list[0] 的值移动到 largest 变量中”。

而在《4.1 什么是所有权》里面,提到 Copy trait 的时候是这么说的:”如果一个类型拥有 Copy trait,一个旧的变量在将其赋值给其他变量后仍然可用“。

我理解的是,4.1 没有说不实现 Copy trait ,就不能移动呀?例如下面的代码,list 里面的是 String,String 好像也没有实现 Copy , 但是也可以将 list[0] 的值移动到 largest。

    let char_list = vec!["a", "av", "a", "q"];
    let list = &char_list; 

    let largest = list[0];
    println!("{}", largest);

希望大家赐教~先谢过了


Ext Link: https://kaisery.github.io/trpl-zh-cn/ch10-02-traits.html

评论区

写评论
作者 liangxiaowei 2020-06-02 09:20

明白了,谢谢回复。 补充一个不能从数组(vector)移动出来代码片段。

let str1 = String::from("a");
let str2 = String::from("a");

let vector = [str1, str2];
let a = vector[0];

而不能移动出来的原因,我理解的是:假设赋值语句可以运行,所有权就会从数组 move 到变量 a 中,这样数组就需要标记自己哪些元素的所有权丧失了,但是数组不负责这个事情。 参考这篇文章 https://www.oreilly.com/library/view/programming-rust/9781491927274/ch04.html 的 Moves and Indexed Content 小节 对以下内容的回复:

whfuyn 2020-06-01 23:52

看了下原文:

 But when we made the largest function generic, it became possible for the list parameter to have types in it that don’t implement the Copy trait. Consequently, we wouldn’t be able to move the value out of list[0] and into the largest variable, resulting in this error.

这里的意思并不是没有实现Copy就不能移动(move)。因为Rust里move是默认行为,除非实现了Copy,否则都是move。 这里应该是想说:因为有可能有的类型不是Copy的,所以我们只能以move来考虑,我们无法把一个值从一个数组里move出来,所以导致了这个错误。

whfuyn 2020-06-01 23:32
let char_list = vec!["a", "av", "a", "q"];
let list = &char_list; 

let largest = list[0];
println!("{}", largest);

list里面不是String而是&str,而不可变引用是Copy的,见https://doc.rust-lang.org/std/primitive.reference.html#impl-Copy

Rust里的字符串有好多种,这是一个难点要注意区分。

“意味着我们可能不能将 list[0] 的值移动到 largest 变量中”这句话有问题,这里的移动应该为拷贝(Copy)。

1 共 3 条评论, 1 页