1.自己对关于记录(1)中引用问题的解答
今天学到特征Trait,看到了昨日遗留的问题,对largest函数的修改
//圣经
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let result = largest(&number_list);
println!("The largest number is {}", result);
}
圣经中说道“如果并不希望限制largest函数只能用于实现了Copy特征的类型,我们可以在T的特征约束中只能。。。。另一种largest的实现方式是返回在list中T值的引用。如果我们将函数返回值从T改为&T并改变函数体使其能够返回一个引用,我们将不需要Clone或Copy的特征约束而且也不会用任何的堆分配”
特征 Trait - Rust语言圣经(Rust Course)
、、
下面的方式是“Rust程序设计”一书中提到的方法,也是就让我觉得怪怪的方法:
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let result = largest(&number_list);
println!("The largest number is {}", result);
}
详细点(gpt4):
1.两个函数传入的是不可变数组切片&[T],let mut largest = list[0]是第一个值,&list[0]是引用
2.在for循环中,iter()是显示方法,无论加不加,for i in item的i都是&T类型(因为对不可变数组切片使用for返回的是不可变引用迭代)
3.在“”rust程序设计“”因为实现了PartialOrd(Ord)特性,所以在if比较时候,rust对&T自动解引用,如果没有特性,则无法完成自动解引用,无法比较
2.vector借用的问题
看评论看到一个有意思的例子:
// Error
let mut v = vec![1,2,3,4];
let f: &i32 = &v[0];
v.push(6);
println!("{}",f);
//correct
let mut v = vec![1,2,3,4];
let v1 = &v;
let f: i32 = v1[0]; //v1不可变借用结束
v.push(6); // 可变借用可用
println!("{}",f);
这里按照借用规则,第一个在编译时候,检测到不可变借用和可变借用,并且不可变借用的周期包裹可变借用,所以报错,第二个问题,因为f发生值拷贝,没有借用,v1的不可变借用在f值拷贝之后作用域结束,此时可以使用可变借用,所以v.push顺利实现
3.派生特征trait
对圣经的这个例子:动态数组 Vector - Rust语言圣经(Rust Course)
#[derive(Debug, Ord, Eq, PartialEq, PartialOrd)]
struct Person {
name: String,
age: u32,
}
impl Person {
fn new(name: String, age: u32) -> Person {
Person { name, age }
}
}
fn main() {
let mut people = vec![
Person::new("Zoe".to_string(), 25),
Person::new("Al".to_string(), 60),
Person::new("Al".to_string(), 30),
Person::new("John".to_string(), 1),
Person::new("John".to_string(), 25),
];
people.sort_unstable();
println!("{:?}", people);
}
由如下附录可知:
派生特征 trait - Rust语言圣经(Rust Course)
PartialEq
特征可以比较一个类型的实例以检查是否相等,并开启了 ==
和 !=
运算符的功能。
派生的 PartialEq
实现了 eq
方法。当 PartialEq
在结构体上派生时,只有所有 的字段都相等时两个实例才相等,同时只要有任何字段不相等则两个实例就不相等。
Eq
特征没有方法, 其作用是表明每一个被标记类型的值都等于其自身。 Eq
特征只能应用于那些实现了 PartialEq
的类型
PartialOrd
特征可以让一个类型的多个实例实现排序功能。实现了 PartialOrd
的类型可以使用 <
、 >
、<=
和 >=
操作符。一个类型想要实现 PartialOrd
的前提是该类型已经实现了 PartialEq
。当在结构体上派生时, PartialOrd
以在结构体定义中字段出现的顺序比较每个字段的值来比较两个实例。