Rust
文章平均质量分 84
Rust
Andy技术支援
技术支援、支持,主要方向:Java、AI、类脑技术、区块链
展开
-
Rust-Panic
在Rust中,有一类错误叫作panic。示例如下:编译,没有错误,执行这段程序,输出为:这种情况就引发了一个panic。在这段代码中,我们调用了Option::unwrap()方法,正是这个方法有可能导致panic。根据提示,我们设置一个环境变量RUST_BACKTRACE=1之后再执行这个程序,可以看到这个程序在发生panic时候的函数调用栈。原创 2024-01-16 11:47:55 · 577 阅读 · 0 评论 -
Rust-泄漏
在C++中,如果引用计数智能指针出现了循环引用,就会导致内存泄漏。而Rust中也一样存在引用计数智能指针Rc,那么Rust中是否可能制造出内存泄漏呢?原创 2024-01-16 10:34:00 · 1084 阅读 · 0 评论 -
Rust-解引用
解引用操作可以被自定义。方法是,实现标准库中的std::ops::Deref或者std::ops::DerefMut这两个trait。Deref的定义如下所示。DerefMut的唯一区别是返回的是&mut型引用都是类似的,因此不过多介绍了。这个trait有一个关联类型Target,代表解引用之后的目标类型。比如,标准库中实现了String向str的解引用转换:deref()方法返回的类型是&Target,而不是Target。原创 2024-01-16 10:09:16 · 1082 阅读 · 0 评论 -
Rust-内部可变性
Rust的borrow checker的核心思想是“共享不可变,可变不共享”。但是只有这个规则是不够的,在某些情况下,我们的确需要在存在共享的情况下可变。为了让这种情况是可控的、安全的,Rust还设计了一种“内部可变性”(interior mutability)。“内部可变性”的概念,是与“承袭可变性”(inherited mutability)相对应的。大家应该注意到了,Rust中的mut关键字不能在声明类型的时候使用,只能跟变量一起使用。类型本身不能规定自己是否是可变的。原创 2024-01-16 09:44:37 · 1125 阅读 · 0 评论 -
Rust-NLL(Non-Lexical-Lifetime)
Rust防范“内存不安全”代码的原则极其清晰明了。如果你对同一块内存存在多个引用,就不要试图对这块内存做修改;如果你需要对一块内存做修改,就不要同时保留多个引用。只要保证了这个原则,我们就可以保证内存安全。它在实践中发挥了强大的作用,可以帮助我们尽早发现问题。这个原则是Rust的立身之本、生命之基、活力之源。这个原则是没问题的,但是,初始的实现版本有一个主要问题,那就是它让借用指针的生命周期规则与普通对象的生命周期规则一样,是按作用域来确定的。原创 2024-01-15 20:55:54 · 1071 阅读 · 1 评论 -
Rust-借用检查
Rust语言的核心特点是:在没有放弃对内存的直接控制力的情况下,实现了内存安全。所谓对内存的直接控制能力,前文已经有所展示:可以自行决定内存布局,包括在栈上分配内存,还是在堆上分配内存;支持指针类型;可以对一个变量实施取地址操作;有确定性的内存释放;等等。另一方面,从安全性的角度来说,我们可以看到,Rust有所有权概念、借用指针、生命周期分析等这些内容。随便写个小程序都编译不通过,学习曲线非常陡峭。那么,Rust设计者究竟是如何考虑的这个问题,为什么要设计这样复杂的规则?原创 2024-01-15 17:13:10 · 985 阅读 · 0 评论 -
Rust-借用和生命周期
test返回的那个指针在’t这个生命周期范围内都是合法的,在一个被’t包围的更小范围的生命周期内,它当然也是合法的。在函数被调用的时候,它传人的实际参数是&t,它是指向t的引用。要特别说明的是,若是有where T:'static的约束,意思则是,类型T里面不包含任何指向短生命周期的借用指针,意思是要么完全不包含任何借用,要么可以有指向’static的借用指针。select函数的形式参数要求的是同样的生命周期,而实际参数是两个不同生命周期的引用,这个类型之所以可以匹配成功,就是因为生命周期的协变特性。原创 2024-01-15 16:39:53 · 1351 阅读 · 0 评论 -
Rust-析构函数
所谓“析构函数”(destructor),是与“构造函数”(constructor)相对应的概念。“构造函数”是对象被创建的时候调用的函数,“析构函数”是对象被销毁的时候调用的函数。Rust中没有统一的“构造函数”这个语法,对象的构造是直接对每个成员进行初始化完成的,我们一般将对象的创建封装到普通静态函数中。相对于构造函数,析构函数有更重要的作用。它会在对象消亡之前由编译器自动调用,因此特别适合承担对象销毁时释放所拥有的资源的作用。原创 2024-01-15 13:12:34 · 1304 阅读 · 0 评论 -
Rust-所有权和移动语义
拿C语言的代码来打个比方。然而,这段代码之后,谁能猜得到,指针p指向的对象究竟发生了什么?它是否被修改过了?它还存在吗,是否已经被释放?是否有另外一个指针现在也同时指向这个对象?我们还能继续读取、修改或者释放这个对象吗?实际上,除了去了解use_object的内部实现之外,我们没办法回答以上问题。对此,C++进行了一个改进,即通过“智能指针”来描述“所有权”(Ownership)概念。这在一定程度上减少了内存使用bug,实现了“半自动化”的内存管理。原创 2024-01-15 10:49:00 · 1128 阅读 · 0 评论 -
Rust-内存安全
堆是在内存中动态分配的内存,是无序的。同样,内存耗尽也不是事关安全性的问题,出现内存耗尽的时候,Rust程序的行为依然是确定性的和可控的(目前版本下,如果内存耗尽则发生panic,也有人认为在这种情况发生的时候,应该给个机会由用户自己处理,这种情况后面应该会有改进)。某些应用场景下用这样的代价换取开发效率和安全性是非常划算的,而在某些应用场景下这样的代价是不可接受的。内存泄漏显然是一种bug,但是它不会直接造成非常严重的后果,至少比上面列出的那些错误危险性要低一些,解决的办法也是完全不一样的。原创 2024-01-14 18:08:24 · 1032 阅读 · 1 评论 -
Rust-模式解构
下划线表示省略一个元素,两个点可以表示省略多个元素。原创 2024-01-13 21:39:17 · 567 阅读 · 0 评论 -
Rust-数组
数组是一个容器,它在一块连续空间内存中,存储了一系列的同样类型的数据。数组中元素的占用空间大小必须是编译期确定的。数组本身所容纳的元素个数也必须是编译期确定的,执行阶段不可变。如果需要使用变长的容器,可以使用标准库中的Vec/LinkedList等。数组类型的表示方式为[T;n]。其中T代表元素类型;n代表元素个数;它必须是编译期常量整数;中间用分号隔开。原创 2024-01-13 20:04:47 · 1224 阅读 · 0 评论 -
Rust-trait
Rust语言中的trait是非常重要的概念。在Rust中,trait这一个概念承担了多种职责。在中文里,trait可以翻译为“特征”“特点”“特性”等。原创 2024-01-13 19:23:44 · 978 阅读 · 0 评论 -
Rust-函数
Rust的函数使用关键字fn开头。函数可以有一系列的输入参数,还有一个返回类型。函数体包含一系列的语句(或者表达式)。函数返回可以使用return语句,也可以使用表达式。Rust编写的可执行程序的入口就是fn main()函数。以下是一个函数的示例:函数体内部是一个表达式,这个表达式的值就是函数的返回值。也可以写returnx+y;这样的语句作为返回值,效果是一样的。函数也可以不写返回类型,在这种情况下,编译器会认为返回类型是unit()。此处和表达式的规定是一致的。原创 2024-01-13 17:46:43 · 516 阅读 · 0 评论 -
Rust-语句和表达式
因为编译器会觉得while语句的执行跟条件表达式在运行阶段的值有关,因此它不确定x是否一定会初始化,于是它决定给出一个错误:use of possibly uninitialized variable,也就是说变量x可能没有初始化。if-else表达式的构成方式为:以if关键字开头,后面跟上条件表达式,后续是结果语句块,最后是可选的else块。主要原因在于,相比于其他的许多语言,Rust语言要做更多的静态分析。在loop内部break的后面可以跟一个表达式,这个表达式就是最终的loop表达式的值。原创 2024-01-13 11:20:18 · 484 阅读 · 0 评论 -
Rust-类型
Rust的这一策略与C语言不同,C语言标准中对许多类型的大小并没有做强制规定,比如int、long、double等类型,在不同平台上都可能是不同的大小,这给许多程序员带来了不必要的麻烦。相反,在语言标准中规定好各个类型的大小,让编译器针对不同平台做适配,生成不同的代码,是更合理的选择。如果说tuple、struct、tuple struct在Rust中代表的是多个类型的“与”关系,那么 enum类型在Rust中代表的就是多个类型的“或”关系。它们占据的空间是不定的,与指针占据的空间一致,与所在的平台相关。原创 2024-01-12 20:09:07 · 910 阅读 · 2 评论 -
Rust-变量
Rust的变量必须先声明后使用。与传统的C/C++语言相比,Rust的变量声明语法不同。这样设计主要有以下几个方面的考虑。语法分析更容易从语法分析的角度来说,Rust的变量声明语法比C/C++语言的简单,局部变量声明一定是以关键字let开头,类型一定是跟在冒号:的后面。语法歧义更少,语法分析器更容易编写。方便引入类型推导功能Rust的变量声明的一个重要特点是:要声明的变量前置,对它的类型描述后置。这也是吸取了其他语言的教训后的结果。原创 2024-01-12 18:52:40 · 1014 阅读 · 0 评论