让学习快乐起来,想不通的就不要想
泛型 ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
泛型思想广泛应用于 trait,enum, 以及T,并且标准库往往会组合使用,如果不理解泛型,不理解这些组合,就难以写出漂亮的代码。这种对事务的抽象概括,业务的抽象,数据建模我认为才是编程最让人痴迷的地方。毕竟我们写代码就像青钢影,要优雅
但是代码没有什么说的,T
就是语法
trait ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
- 接口
至少到现在我觉得都是接口,接口定义行为,比如usb,typec就是一种接口思想,所有实现了usb的元件都可以通过usb进行数据接入。
编译器定义了一批接口,比如from()和in_to(),这是两个相关的接口。就是说你实现from,编译器会帮你实现into,我们来看看为什么要这么做
struct Point {
x: i32,
y: i32,
}
// 为 Point 实现 From<(i32, i32)>
impl From<(i32, i32)> for Point {
println!("from called");
fn from(tuple: (i32, i32)) -> Self {
Point {
x: tuple.0,
y: tuple.1,
}
}
}
fn main() {
let tuple = (10, 20);
// 使用 From 实现
let point_from = Point::from(tuple);
println!("Point from: ({}, {})", point_from.x, point_from.y);
// 使用 Into 实现
let point_into: Point = tuple.into();
println!("Point into: ({}, {})", point_into.x, point_into.y);
}
// 这段代码会打印两次from called,说明确实是语法糖
// 你会不会想,我可以不用into吗,当然可以!
// 但是你就需要调用new方法去创建这个对象,但是rust觉得如果我能知道你该怎么实现,那你调用一下in_to(),我就在编译器层面调用from,这就是一个语法糖。让你写代码更加优雅。毕竟转换的代码在静态语言里面都是非常多的,而且需要考虑所有权,我们来看一个方法
// "hello".in_to(),会返回一个String,返回了所有权。这样是不是比 new_string("hello")好一点。
生命周期 ✨✨✨✨✨✨
在函数签名中,生命周期参数用 'a、'b 等表示。生命周期参数并不改变引用的实际生命周期,而是用来描述引用之间的关系。
//下面这个代码是比较a,b两个str的长度的。并且返回比较长的那一个。对于调用者来说我肯定希望返回的是一个引用。但是这个引用是不知道是谁的引用的。有可能是a,有可能是b。这样就麻烦了
//如何确定返回引用的生命周期呢,这个问题比较麻烦。实际上编译器只是部分解决了这个问题。所以遇到生命周期的时候一定要谨慎
// 下面的函数定义了 'a 生命周期,并且返回了 'a, 这只是说表明,返回的引用的生命周期跟X还有Y是相关联的。换句话的意思就是,返回值的生命周期有可能是X的生命周期,有可能是Y的生命周期,编译器需要保证,返回值的生命周期不能超过短的那个
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
println!("The longest string is {}", result);
}
// 如果你在这里使用result,result有可能是string1,也有可能是string2.如果是string1,看起来应该是可以的。但是如果是string2,是不是就报错了,所以这样的代码无法通过编译,
println!("longger result: {}", result)
}
模式匹配 ✨✨✨✨✨✨
运算符号,说实话,符号是比较多
- @ 绑定
- … 范围
- | 或
let x = 4;
let y = false;
match x {
// 4或者5或者6
4 | 5 | 6 if y => println!("yes"),
_ => println!("no"),
}
// 定义一个枚举
enum Message {
Hello { id: i32 },
}
// 实例化一个枚举类型
let msg = Message::Hello { id: 5 };
// 匹配当前枚举
match msg {
// @运算符
// 是否在3,4,5,6,7,这几个枚举里面,如果匹配到了,就将这个值赋给 id_variable,
Message::Hello {
id: id_new_variable @ 3..=7,
} => println!("Found an id in range: {id_new_variable}"),
// ..运算符
// 是否在10到12里面
Message::Hello { id: 10..=12 } => {
println!("Found an id in another range")
}
Message::Hello { id } => println!("Found some other id: {id}"),
}
来一个 图书馆项目试试手吧 ✨✨✨✨✨✨
需求设计
- 添加书籍:能够添加新书籍,包括书名、作者、ISBN和出版年份。
- 查看书籍:能够查看所有书籍列表以及单本书籍的详细信息。
- 更新书籍:能够更新书籍的信息。
- 删除书籍:能够删除书籍。
reference:https://kaisery.github.io/trpl-zh-cn/ //rustlings