语言基础篇
类型系统
泛型
函数名使用snake case
规范风格
struct Rectangle1<T> {
width: T,
height: T,
}
struct Rectangle2<T, U> {
width: T,
height: U,
}
impl<T> Rectangle1<T> {
fn width(&self) -> &T {
&self.width
}
fn height(&self) -> &T {
&self.height
}
}
impl Rectangle1<i32> {
fn area(&self) -> i32 {
self.width * self.height
}
}
impl<T, U> Rectangle2<T, U> {
fn width(&self) -> &T {
&self.width
}
fn height(&self) -> &U {
&self.height
}
}
fn main() {
let rect1 = Rectangle1 {width: 8, height: 2};
println!("rect1.width: {}, rect1.height: {}", rect1.width(), rect1.height());
println!("rect1.area: {}", rect1.area());
let rect2 = Rectangle2 { width: 8, height: 2.2};
println!("rect2.width: {}, rect2.height: {}", rect2.width(), rect2.height());
}
Rectangle1
泛型是T,所以不能前后不一致,例如前面是i32,后面就不能是f64,但是Rectngle2
就可以前后类型不一致
泛型与枚举
fn option_add(x: Option<i32>, y: Option<i32>) -> Option<i32> {
return if x.is_none() && y.is_none() { None }
else if x.is_none() { y }
else if y.is_none() { x }
else { Some(x.unwrap() + y.unwrap()) };
}
fn option_print(opt: Option<i32>) {
match opt {
Some(result) => println!("Option: {}", result),
_ => println!("Option is None!"),
}
}
fn main() {
let result1 = option_add(Some(3), Some(5));
let result2 = option_add(Some(3), None);
let result3 = option_add(None, None);
option_print(result1);
option_print(result2);
option_print(result3);
}
// enum Option<T> {
// Some<T>,
// None,
// }
这里在写option<T>
的泛型使用方法
泛型与函数
函数的参数与返回值都可以是泛型类型
泛型也可以写方法,具体函数见泛型
trait系统
在几何图形中,都会求周长与面积,而其周长与面积的方法就可以写进一个trait中
trait Geometry {
fn area(&self) -> f32;
fn perimeter(&self) -> f32;
}
这个可以在impl中实现
trait Geometry {
fn area(&self) -> f32;
fn perimeter(&self) -> f32;
}
struct Rectangle {
width: f32,
height: f32,
}
impl Geometry for Rectangle {
fn area(&self) -> f32 {
self.width * self.height
}
fn perimeter(&self) -> f32 {
(self.width + self.height) * 2.0
}
}
struct Circle {
radius: f32,
}
impl Geometry for Circle {
fn area(&self) -> f32 {
3.14 * self.radius * self.radius
}
fn perimeter(&self) -> f32 {
3.14 * 2.0 * self.radius
}
}
fn main() {
let rect = Rectangle {width: 8.0, height: 2.0};
println!("rect.area: {}, rect.perimeter: {}",
rect.area(), rect.perimeter())
}
就像接口一样,但是可以作为参数,比其他语言的接口更方便
trait Geometry {
fn area(&self) -> f32;
fn perimeter(&self) -> f32;
}
fn print(geometry: impl Geometry) {
println!("area: {}, perimeter: {}",
geometry.area(), geometry.perimeter())
}
struct Rectangle {
width: f32,
height: f32,
}
impl Geometry for Rectangle {
fn area(&self) -> f32 {
self.width * self.height
}
fn perimeter(&self) -> f32 {
(self.width + self.height) * 2.0
}
}
fn main() {
let rect = Rectangle {width: 8.0, height: 2.0};
print(rect);
}
将原本的接口再次进行了包装
fn可以在impl中写并运用trait做接口
也可用多个trait做接口
也可将返回值设为trait
fn return_geometry() -> impl Geometry {
Rectangle {
width: 12.5,
height: 5.5,
}
}
NaN != NaN
enum BookFormat {
Paperback,
Hardback,
Ebook,
}
struct Book {
isbn: i32,
format: BookFormat,
}
impl PartialEq for Book {
fn eq(&self, other: &Self) -> bool {
self.isbn == other.isbn
}
}
这里重写了eq方法,只要两个Book
的isbn相同,就是同一本书
类型转换
let x : u16 = 7;
let y = x as u32;
let x = std::u32::MAX
let y = x as u16;
可以进行放缩