自定义数据类型 本文中概念在Rust高手ChatGPT指导下学习 Struct 结构体 定义结构体 没有什么花里胡哨的,使用struct关键字加上结构体名称就好,字段名可以不指定(元组结构体,用括号代替大括号),字段类型必须指定(单元结构体除外,不需要括号)
⚠️注意,结构体实例化时是等效赋值语句的,所以如果使用结构体更新语法,从现有结构体实例中更新一个新的结构体,如果字段是类似String这样在堆上的数据类型,更新会等效所有权中的移动,也就是原实例失效,再使用时会报E0382部分所有权移动错误。(吐槽:Rust高手没有指出这个问题,并且在给出示例的时候信誓旦旦这样不会有问题…但是丢到rust-analyze里一下子就被指出来问题惹)
如果是更新具有copy trait的类型,而非获取所有权不影响原结构体实例。
可以通过将字段类型改为引用的方式,避免更新结构体时所有权移动的问题,但是需要定义生命周期,后续进一步学习。
结构体方法和关联函数 方法这个概念在Python这些强OOP的语言当中应该是一个比较常见的概念,这里不赘述了。除了定义在impl块内,定义方法和定义普通函数并无不同,但是方法的第一个参数为self(self:Self的简写,Self类型是impl块的类型的别名),这里self和其他变量并无不同,可以是&self也就是实例的自身引用。
和C++不同,Rust在处理对象的方法与对象引用的方法时,并无差别,因为Rust会自动解引用。 impl块中定义的函数,都被称之为关联函数,只是其中以self为第一个参数的会被称为方法。不是方法的关联函数经常被用作返回一个结构体新实例的构造函数。结构体名和 :: 语法来调用这个关联函数。
Enums 枚举 定义 使用enum关键字定义自定义类型和成员,例如:
enum IpAddrKind { V4, V6, } 枚举值,通过let定义,而枚举成员位于其标识符的命名空间中,因此采用::表示。
关联类型 可以通过将数据类型放入枚举成员,而不是将枚举作为结构体的一部分,此时枚举成员的名字也变成了一个构建枚举的实例的函数。
enum IpAddr { V4(u8, u8, u8, u8), V6(String), } let home = IpAddr::V4(127,0,0,1); let loopback = IpAddr::V6(String::from("::1")); 关联方法 与结构体相似,枚举也是使用impl来定义关联方法,不再赘述
Option 枚举 作为标准库定义的枚举,针对一个值要么有要么没有值的场景。没错,Rust中没有空值null的实现。但是没有null值并不代表没有空的概念,因此Rust通过枚举类型来解决这个问题。Option的定义如下:
enum Option<T> { None, Some(T), } 难道这里的None不就是null换了个名字吗?不是的,因为Option<T>和 T(这里 T 可以是任何类型)是不同的类型,编译器不允许像一个肯定有效的值那样使用 Option<T>,会报E0277错误
...