Rust学习日记0x02

自定义数据类型 本文中概念在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错误 ...

March 21, 2023 · 1 min · 151 words · x1a0y4o

Rust学习日记0x01

在寒假期间简单对Rust的数据类型和语法有了一个粗浅的了解之后,卡在了Ownership这个不同于其他编程语言的内存管理概念上。由于很少有实践,学习Rust就暂时搁置了下来,而在GPT-4和Cursor推出以后,再次燃起了一些兴趣。本文便是用于记录在AI助教的帮助下学习Rust语言的过程。 入门扫盲——基础编程概念 在有其他语言的基础上,理解起来不会太费劲的概念。但是也需要注意不同语言之间的区别。 变量:一个默认不会变的量,因此它如果会变,请定义时加上mut。 不可变变量是不可以二次赋值的,但是可以重新let x定义,此时第一个值会被隐藏。通常这一点可以应用在不同作用域。 同时,与使用mut相比,重新赋值还可以改变变量的数据类型(因为本质上是定义了一个同名的新变量)。 与不可变变量相比,常量更加不可变,并且在定义时需要显式定义数据类型。 数据类型:分为两个子类scalar标量和compound复合类型 整型:与大部分静态语言相同。不过出现整形溢出时,debug模式编译器会报Panic而release模式会默认补码操作,但是这种wrapping的行为不太好 浮点型:f32与f64(default),分别是单精度与双精度 布尔型:true和false 字符型:char,4字节的unicode标量值,用单引号包围;与之相对的双引号用来包围字符串字面量 元组:tuple,一个非常熟悉的概念,元组的长度是固定的 数组:array,同样熟悉的概念,但是在Rust中,数组成员类型必须相同并且长度也是固定的。 Vector:尽管Vector并非原生复合类型,但是作为标准库提供的一种可以改变长度的类似数组的复合类型,还是在这里提一下,后续应该会深入学习 函数: 定义:使用关键字fn定义,函数定义的顺序无所谓,只要调用时处于调用处可见的作用域中即可 参数:parameters是函数签名的一部分,调用时用来传入arguments。在Rust中,定义参数时必须提供类型注解。 语句和表达式:前者执行操作但不返回值,后者计算并返回值。Rust是一门基于表达式的语言。函数调用是一个表达式。宏调用是一个表达式。用大括号创建的一个新的块作用域也是一个表达式 函数返回值:不需要对返回值命名,但是需要提供类型注解。并且隐式返回最后的表达式 控制流: if表达式:没什么太多好说的,唯一需要注意的可能是Rust中if表达式的条件必须是bool类型的值,与动态语言会自动转换不同。另外,如果想要在赋值语句中应用if表达式,需要保证不同分支结果的变量类型一致。 循环结构:loop和while以及for,都是常见的循环结构,不过Rust中可以定义循环标签,方便break和continue控制循环层。 Ownership所有权 一个与我此前学过的语言迥异的概念,解释起来其实并不复杂,但是很难适应。 Ownership的意义:一种内存管理机制,为了更好的追踪和分配堆上的内存。 Ownership的规则 Rust中的每一个值都有一个所有者 值在任一时刻有且只有一个所有者 当所有者(变量)离开作用域,这个值将被丢弃 变量的作用域scope:从声明直到作用域结束 通过String理解所有权 String是第二个字符串类型,用于未知大小的字符串。 2023-03-19 果然到Ownership就会半途而废是吗( 移动 是否可以理解成,当Rust处理堆上内存时,为了避免二次释放,所以浅拷贝不存在了,而是所有权的转移。或者说是发生浅拷贝之后,原变量不再拥有所有权了。 而深拷贝(Clone),永远不会自动创建。 拷贝 Copy是一个trait,不同于Clone,因为处理的对象是栈上的内存,所以并不会带来太多性能损耗。但是不允许自身或任何部分实现了Drop trait的类型使用。Drop是自动在变量离开作用域时调用的函数,用于释放内存。 引用与借用 reference可以理解成永远指向有效值的指针。使用&表示。 创建引用的行为称之为借用,借用但是并不拥有值的所有权。所以当引用停止时并不需要通过返回值交还所有权。 如果需要修改引用对象的值,需要创建一个可变引用。关于可变引用有一些规则,为了避免数据竞态(果然Rust的设计没有写过很多C是体会不出来的),这里简单罗列一下: 不能同时创建两个可变引用 可以创建多个不可变引用 创建可变引用后,不可以再使用不可变引用 另外,Rust通过生命周期解决了垂悬引用的问题。我们日后再深究 Slice Pythonista多么熟悉的概念 设计slice是为了解决索引与对象本身不关联的问题(令人大开眼界) Slice的语法是..,索引从0开始,可以省略开头和结尾(再次熟悉) 字符串的字面值就是Slice let s = "Hello, world!"; 此处s的类型居然是&str,是一个指向二进制程序特定位置的不可变引用 2023-03-20:为了保证学习可持续,本系列打算高频更新以督促进度,所以可能学到一部分知识点就发一次,虽然零碎但是起码能保证一点一点学习,可能后面会考虑再整理吧

March 19, 2023 · 1 min · 62 words · x1a0y4o

First Post in CSU

The first blog written in CSU,also the first one written by vim editor. 来到中南约莫有一个月了,回顾了一下自己的生活,其实还是有很多值得记录下来 生活 说实话感觉长沙与武汉还是有很多相似的地方,不管是气候还是饮食。但是铁道附近的餐饮实在是令人一言难尽,都说长沙是美食城市,偏偏在铁道附近形成了一块黑洞。学校周边的湘菜净是些油腻重口的菜,不是辣椒炒肉便是辣椒炒辣椒。每道菜的做法看起来简直是一模一样,肉切的小小的碎碎的,虽然下饭,但不能多吃。 长沙的天气,和武汉真的很像,但是可能没有大江大河,所以相比起来有些干燥。太阳也毒辣许多,刚来一个星期皮肤就黑了一个度,赶紧打起伞来。 学业 实验室的氛围出乎意料的放松,原本毕业设计时期对老谢PUSH狂魔的印象也发生了翻天覆地的变化。师兄们都非常温和而亲切,逾严师兄甚至直接把分配给他的PC让给了我,大师兄在第一次组会就让我觉得是一大好人,让我想起了花姐。果然,后来PHM课题组的第一次聚餐,酒桌上最后的赢家大师兄送走了所有师弟,和我一起慢慢悠悠晃回宿舍,讲了很多课题组的故事。其他的同门也非常友善。长沙,jin好。 但是老谢布置的课题真的很难,-idea已打码-,总之就是很难实现,头秃。 剩下的还有好多好多,但是今天已经11月2号了,再拖下去这篇处女blog就永远也发不出来了。后续应该会更多更新一些技术方面的Blog,下次见~

September 20, 2022 · 1 min · 21 words · x1a0y4o