自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(960)
  • 收藏
  • 关注

原创 Rust从入门到实战系列五十九:match 控制流运算符

这看起来非常像 if 使用的表达式,不过这里有一个非常大的区别:对于 if,表达式必须返回一个布尔值,而这里它可以是任何类型的。Rust 有一个叫做 match 的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。同样地,值也会通过 match 的每一个模式,并且在遇到第一个 ” 符合” 的模式时,值会进入相关联的代码块并在执行中被使用。接下来是 match 的分支。每个分支相关联的代码是一个表达式,而表达式的结果值将作为整个 match 表达式的返回值。

2024-03-01 08:48:41 69

原创 Rust从入门到实战系列五十八:Option 枚举和其相对于空值的优势

例如,如果请求一个包含项的列表的第一个值,会得到一个值,如果请求一个空的列表,就什么也不会得到。match 表达式就是这么一个处理枚举的控制流结构:它会根据枚举的成员运行不同的代码,这些代码可以使用匹配到的值中的数据。目前,所有你需要知道的就是 意味着 Option 枚举的 Some 成员可以包含任意类型的数据,同时每一个用于 T 位置的具体类型使得 Option 整体作为不同的类型。我称之为我十亿美元的错误。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。

2024-03-01 08:46:01 182

原创 Rust从入门到实战系列五十七:枚举值

这里我们定义了一个有两个字段的结构体 IpAddr:IpAddrKind(之前定义的枚举)类型的 kind 字段和 String 类型 address 字段。这里也很容易看出枚举工作的另一个细节:每一个我们定义的枚举成员的名字也变成了一个构建枚举的实例的函数。注意虽然标准库中包含一个 IpAddr 的定义,仍然可以创建和使用我们自己的定义而不会有冲突,因为我们并没有将标准库中的定义引入作用域。Message 枚举那样,轻易的定义一个能够处理这些不同类型的结构体的函数,因为枚举是单独一个类型。

2024-03-01 08:42:32 153

原创 Rust从入门到实战系列五十六:枚举和模式匹配

接下来,我们会探索一个特别有用的枚举,叫做 Option,它代表一个值要么是某个值要么什么都不是。这是我们的程序可能会遇到的所有可能的 IP 地址类型:所以可以 枚举出所有可能的值,这也正是此枚举名字的由来。任何一个 IP 地址要么是 IPv4 的要么是 IPv6 的,而且不能两者都是。IP 地址的这个特性使得枚举数据结构非常适合这个场景,因为枚举值只可能是其中一个成员。IPv4 和 IPv6 从根本上讲仍是 IP 地址,所以当代码在处理适用于任何类型的 IP 地址的场景时应该把它们当作相同的类型。

2024-03-01 08:37:42 60

原创 Rust从入门到实战系列五十五:关联函数

所有在 impl 块中定义的函数被称为 关联函数(associated functions),因为它们与 impl 后面命名的类型相关。我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例。结构体让你可以创建出在你的领域中有意义的自定义类型。在 impl 块中,你可以定义与你的类型相关联的函数,而方法是一种相关联的函数,让你指定结构体的实例所具有的行为。但结构体并不是创建自定义类型的唯一方法:让我们转向 Rust 的枚举功能,为你的工具箱再添一个工具。

2024-03-01 08:35:47 64

原创 Rust从入门到实战系列五十四:-> 运算符到哪去了?

通过观察调用方法的代码可以看出参数是什么类型的:rect1.can_hold(&rect2) 传入了 &rect2,它是一个 Rectangle 的实例 rect2 的不可变借用。这是可以理解的,因为我们只需要读取 rect2(而不是写入,这意味着我们需要一个不可变借用),而且希望 main保持 rect2 的所有权,这样就可以在调用这个方法后继续使用它。在给出接收者和方法名的前提下,Rust 可以明确地计算出方法是仅仅读取(&self),做出修改(&mut self)或者是获取所有权(self)。

2024-03-01 08:33:24 208

原创 Rust从入门到实战系列五十三:方法语法

在这里,我们选择让 width 方法在实例的 width 字段的值大于 0 时返回 true,等于 0 时则返回 false:我们可以出于任何目的,在同名的方法中使用同名的字段。不过方法与函数是不同的,因为它们在结构体的上下文中被定义(或者是枚举或 trait 对象的上下文,将分别在第六章和第十七章讲解),并且它们第一个参数总是 self,它代表调用该方法的结构体实例。Getters 很有用,因为你可以把字段变成私有的,但方法是公共的,这样就可以把对字段的只读访问作为该类型公共 API 的一部分。

2024-03-01 08:30:33 214

原创 Rust从入门到实战系列五十二:通过派生 trait 增加实用功能

除了 Debug trait,Rust 还为我们提供了很多可以通过 derive 属性来使用的 trait,他们可以为我们的自定义类型增加实用的行为。我们可以看到第一点输出来自 src∕main.rs 第 10 行,我们正在调试表达式 30 * scale,其结果值是 60(为整数实现的 Debug 格式化是只打印它们的值)。我们可以把 dbg!返回表达式的值的所有权,所以 width 字段将获得相同的值,就像我们在那里没有 dbg!宏时所在的文件和行号,以及该表达式的结果值,并返回该值的所有权。

2024-03-01 08:27:49 199

原创 Rust从入门到实战系列五十一:使用元组重构

area 的函数签名现在明确的阐述了我们的意图:使用 Rectangle 的 width 和 height 字段,计算 Rectangle 的面积。不过在另一方面,这个版本却有一点不明确了:元组并没有给出元素的名称,所以计算变得更费解了,因为不得不使用索引来获取元组的每一部分:在计算面积时将宽和高弄混倒无关紧要,不过当在屏幕上绘制长方形时就有问题了!接着在 main 中,我们创建了一个具体的 Rectangle 实例,它的宽是 30,高是 50。元组帮助我们增加了一些结构性,并且现在只需传一个参数。

2024-03-01 08:22:59 130

原创 Rust从入门到实战系列五十:一个使用结构体的示例程序

函数 area 本应该计算一个长方形的面积,不过函数却有两个参数。第三章的 ” 元组类型” 部分已经讨论过了一种可行的方法:元组。使用 Cargo 新建一个叫做 rectangles 的二进制程序,它获取以像素为单位的长方形的宽度和高度,并计算出长方形的面积。这个示例代码在调用 area 函数时传入每个维度,虽然可以正确计算出长方形的面积,但我们仍然可以修改这段代码来使它的意义更加明确,并且增加可读性。为了理解何时会需要使用结构体,让我们编写一个计算长方形面积的程序。

2024-03-01 08:20:57 26

原创 Rust从入门到实战系列四十九:结构体数据的所有权

可以使结构体存储被其他对象拥有的数据的引用,不过这么做的话需要用上 生命周期(lifetimes),这是一个第十章会讨论的 Rust 功能。生命周期确保结构体引用的数据有效性跟结构体本身保持一致。这是一个有意而为之的选择,因为我们想要这个结构体拥有它所有的数据,为此只要整个结构体是有效的话其数据也是有效的。第十章会讲到如何修复这个问题以便在结构体中存储引用,不过现在,我们会使用像 String 这类拥有所有权的类型来替代 &str 这样的引用以修正这个错误。

2024-03-01 08:19:00 41

原创 Rust从入门到实战系列四十八:使用没有命名字段的元组结构体来创建不同的类型

然后,我们可以以类似的方式在 subject 变量中获得 AlwaysEqual 的实例:使用我们定义的名称,不需要任何花括号或圆括号。想象一下,我们将实现这个类型的行为,即每个实例始终等于每一个其他类型的实例,也许是为了获得一个已知的结果以便进行测试。我们将在第十章介绍 trait。你定义的每一个结构体有其自己的类型,即使结构体中的字段有着相同的类型。当你想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的,这时像常规结构体那样为每个字段命名就显得多余和形式化了。

2024-03-01 08:17:19 112

原创 Rust从入门到实战系列四十七:使用字段初始化简写语法

在这个例子中,我们在创建 user2 后不能再使用 user1,因为 user1 的username 字段中的 String 被移到 user2 中。如果我们给 user2 的 email 和 username 都赋予新的String 值,从而只使用 user1 的 active 和 sign_in_count 值,那么 user1 在创建 user2 后仍然有效。因为 email 字段与 email 参数有着相同的名称,则只需编写email 而不是 email: email。

2024-03-01 08:15:35 102

原创 Rust从入门到实战系列四十六:定义并实例化结构体

创建一个实例需要以结构体的名字开头,接着在大括号中使用 key: value 键-值对的形式提供字段,其中 key 是字段的名字,value 是需要存储在字段中的数据值。换句话说,结构体的定义就像一个类型的通用模板,而实例则会在这个模板中放入特定数据来创建这个类型的值。要更改结构体中的值,如果结构体的实例是可变的,我们可以使用点号并为对应的字段赋值。结构体的名字需要描述它所组合的数据的意义。注意整个实例必须是可变的;一样,我们可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例。

2024-03-01 08:12:55 65

原创 Rust从入门到实战系列四十五:其他类型的 slice

struct,或者 structure,是一个自定义数据类型,允许你包装和命名多个相关的值,从而形成一个有意义的组合。还将演示如何定义和实例化结构体,并讨论如何定义关联函数,特别是被称为 方法的那种关联函数,以指定与结构体类型相关的行为。Rust 语言提供了跟其他系统编程语言相同的方式来控制你使用的内存,但拥有数据所有者在离开作用域后自动清除其数据的功能意味着你无须额外编写和调试相关的控制代码。所有权系统影响了 Rust 中很多其他部分的工作方式,所以我们还会继续讲到这些概念,这将贯穿本书的余下内容。

2024-03-01 08:09:27 26

原创 Rust从入门到实战系列四十四:字符串 slice 作为参数

如果有一个字符串 slice,可以直接传递它。如果有一个 String,则可以传递整个 String 的 slice 或对String 的引用。这种灵活性利用了 deref coercions 的优势,这个特性我们将在” 函数和方法的隐式 Deref强制转换” 章节中介绍。

2024-03-01 08:07:04 21

原创 Rust从入门到实战系列四十三:字符串 slice

可以使用一个由中括号中的 [starting_index…ending_index] 指定的 range 创建一个 slice,其中 starting_index是 slice 的第一个位置,ending_index 则是 slice 最后一个位置的后一个值。在其内部,slice 的数据结构存储了 slice 的开始位置和长度,长度对应于 ending_index 减去 starting_index 的值。当找到一个空格,我们返回一个字符串 slice,它使用字符串的开始和空格的索引作为开始和结束的索引。

2024-03-01 08:05:21 70

原创 Rust从入门到实战系列四十二:Slice 类型

所以在 for 循环中,我们指定了一个模式,其中元组中的 i 是索引而元组中的 &item 是单个字节。我们返回了一个独立的usize,不过它只在 &String 的上下文中才是一个有意义的数字。可以尝试用值 5 来提取变量 s 的第一个单词,不过这是有bug 的,因为在我们将 5 保存到 word 之后 s 的内容已经改变。现在,只需知道 iter 方法返回集合中的每一个元素,而 enumerate包装了 iter 的结果,将这些元素作为元组的一部分来返回。如果找到了一个空格,返回它的位。

2024-03-01 08:01:37 146

原创 Rust从入门到实战系列四十一:悬垂引用(Dangling References)

在具有指针的语言中,很容易通过释放内存时保留指向它的指针而错误地生成一个 悬垂指针(danglingpointer),所谓悬垂指针是其指向的内存可能已经被分配给其它持有者。相比之下,在 Rust 中编译器确保引用永远也不会变成悬垂状态:当你拥有一些数据的引用,编译器确保数据不会在其引用之前离开作用域。因为 s 是在 dangle 函数内创建的,当 dangle 的代码执行完毕后,s 将被释放。不过我们尝试返回它的引用。错误信息引用了一个我们还未介绍的功能:生命周期(lifetimes)。

2024-03-01 07:57:53 23

原创 Rust从入门到实战系列四十:可变引用

中使用它,但是在那个可变引用的创建和它的使用之间,我们又尝试在 r2 中创建另一个可变引用,该引用借用与 r1 相同的数据。然后在调用 change 函数的地方创建一个可变引用 &mut s,并更新函数签名以接受一个可变引用 some_string: &mut String。不可变引用的用户可不希望在他们的眼皮底下值就被意外的改变了!然而,多个不可变引用是可以的,因为没有哪个只能读取数据的人有能力影响其他人读取到的数据。可变引用有一个很大的限制:在同一时间只能有一个对某一特定数据的可变引用。

2024-03-01 07:54:13 66

原创 Rust从入门到实战系列三十九:引用与借用

示例 4-5 中的元组代码有这样一个问题:我们必须将 String 返回给调用函数,以便在调用 calculate_length后仍能使用 String,因为 String 被移动到了 calculate_length 内。引用(reference)像一个指针,因为它是一个地址,我们可以由此访问储存于该地址的属于其他变量的数据。变量 s 有效的作用域与函数参数的作用域一样,不过当 s 停止使用时并不丢弃引用指向的数据,因为 s 并没有所有权。同理,函数签名使用 & 来表明参数 s 的类型是一个引用。

2024-02-29 10:12:24 171

原创 Rust从入门到实战系列三十八:所有权与函数

虽然这样是可以的,但是在每一个函数中都获取所有权并接着返回所有权有些啰嗦。如果我们还要接着使用它的话,每次都传进去再返回来就有点烦人了,除此之外,我们也可能想返回函数体中产生的一些数据。试试在 main 函数中添加使用 s 和 x 的代码来看看哪里能使用他们,以及所有权规则会在哪里阻止我们这么做。当持有堆中数据值的变量离开作用域时,其值将通过 drop 被清理掉,除非数据被移动为另一个变量所有。幸运的是,Rust 对此提供了一个不用获取所有权就可以使用值的功能,叫做 引用(references)。

2024-02-29 10:09:21 103

原创 Rust从入门到实战系列三十七:变量与数据交互的方式(二):克隆

Rust 有一个叫做 Copy trait 的特殊注解,可以用在类似整型这样的存储在栈上的类型上(第十章详细讲解 trait)。原因是像整型这样的在编译时已知大小的类型被整个存储在栈上,所以拷贝其实际的值是快速的。你可以查看给定类型的文档来确认,不过作为一个通用的规则,任何一组简单标量值的组合都可以实现 Copy,任何不需要分配内存或某种形式资源的类型都可以实现 Copy。如果我们 确实需要深度复制 String 中堆上的数据,而不仅仅是栈上的数据,可以使用一个叫做 clone 的通用函数。

2024-02-29 10:06:20 146

原创 Rust从入门到实战系列三十六:变量与数据交互的方式(一):移动

不过因为 Rust 同时使第一个变量无效了,这个操作被称为 移动(move),而不是浅拷贝。现在有了两个变量,x 和 y,都等于 5。这也正是事实上发生了的,因为整数是有已知固定大小的简单值,所以这两个 5被放入了栈中。为了确保内存安全,在 let s2 = s1 之后,Rust 认为 s1 不再有效,因此 Rust 不需要在 s1 离开作用域后清理任何东西。这看起来与上面的代码非常类似,所以我们可能会假设他们的运行方式也是类似的:也就是说,第二行可能会生成一个 s1 的拷贝并绑定到 s2 上。

2024-02-29 10:04:11 53

原创 Rust从入门到实战系列三十五:String 类型

在大部分没有 GC 的语言中,识别出不再使用的内存并调用代码显式释放就是我们的责任了,跟请求内存的时候一样。前面介绍的类型都是已知大小的,可以存储在栈中,并且当离开作用域时被移出栈,如果代码的另一部分需要在不同的作用域中使用相同的值,可以快速简单地复制它们来创建一个新的独立实例。不幸的是,我们不能为了每一个在编译时大小未知的文本而将一块内存放入二进制文件中,并且它的大小还可能随着程序运行而改变。这是一个将 String 需要的内存返回给分配器的很自然的位置:当 s 离开作用域的时候。那么这里有什么区别呢?

2024-02-29 10:00:53 264

原创 Rust从入门到实战系列三十四:所有权规则

变量 s 绑定到了一个字符串字面值,这个字符串值是硬编码进程序代码中的。这个变量从声明的点开始直到当前 作用域结束时都是有效的。示例 4-1 中的注释标明了变量 s 在何处是有效的。目前为止,变量是否有效与作用域的关系跟其他编程语言是类似的。现在我们在此基础上介绍 String 类。首先,让我们看一下所有权的规则。• 当 s 进入作用域时,它就是有效的。示例 4-1:一个变量和其有效的作用域。这一直持续到它 离开作用域为止。

2024-02-29 09:57:20 61

原创 Rust从入门到实战系列三十三:认识所有权

因为指针的大小是已知并且固定的,你可以将指针存储在栈上,不过当需要实际数据时,必须访问指针。栈和堆都是代码在运行时可供使用的内存,但是它们的结构不同。跟踪哪部分代码正在使用堆上的哪些数据,最大限度的减少堆上的重复数据的数量,以及清理堆上不再使用的数据确保不会耗尽空间,这些问题正是所有权系统要处理的。出于同样原因,处理器在处理的数据彼此较近的时候(比如在栈上)比较远的时候(比如可能在堆上)能更好的工作。当你的代码调用一个函数时,传递给函数的值(包括可能指向堆上数据的指针)和函数的局部变量被压入栈中。

2024-02-29 09:55:21 86

原创 Rust从入门到实战系列三十二:从循环返回值

这么做的方式是使用 Range,它是标准库提供的类型,用来生成从一个数字开始到另一个数字之前结束的所有数字的序列。这也使程序更慢,因为编译器增加了运行时代码来对每次循环进行条件检查,以确定在循环的每次迭代中索引是否在数组的边界内。例如,在示例 3-4 的代码中,如果你将 a 数组的定义改为有四个元素,但忘记将条件更新为 while index < 4,代码将会 panic。更为重要的是,我们增强了代码安全性,并消除了可能由于超出数组的结尾或遍历长度不够而缺少一些元素而导致的 bug。当条件为真,执行循环。

2024-02-29 09:53:00 181

原创 Rust从入门到实战系列三十一:使用循环重复执行

你可以选择在一个循环上指定一个循环标签(loop label),然后将标签与 break 或 continue 一起使用,使这些关键字应用于已标记的循环而不是最内层的循环。没有标签的内部循环从 10 向下数到 9。幸运的是,Rust 提供了一种从代码中跳出循环的方法。多次执行同一段代码是很常用的,Rust 为此提供了多种 循环(loops)。大部分终端都支持一个快捷键,ctrl-c,来终止一个陷入无限循环的程序。循环中的 continue 关键字告诉程序跳过这个循环迭代中的任何剩余代码,并转到下一个迭代。

2024-02-29 09:45:01 162

原创 Rust从入门到实战系列三十:使用 else if 处理多重条件

if 代码块中的表达式返回一个整数,而 else 代码块中的表达式返回一个字符串。Rust 需要在编译时就确切的知道 number 变量的类型,这样它就可以在编译时验证在每处使用的 number 变量的类型是有效的。且编译器必须跟踪每一个变量的多种假设类型,那么它就会变得更加复杂,对代码的保证也会减少。记住,代码块的值是其最后一个表达式的值,而数字本身就是一个表达式。使用过多的 else if 表达式会使代码显得杂乱无章,所以如果有多于一个 else if 表达式,最好重构代码。

2024-02-29 09:42:35 81

原创 Rust从入门到实战系列二十九:注释

在条件为真时希望执行的代码块位于紧跟条件之后的大括号中。if 表达式中与条件关联的代码块有时被叫做 arms,就像第二章 ” 比较猜测的数字和秘密数字” 部分中讨论到的 match 表达式中的分支一样。在这种情况下,程序员在源码中留下 注释(comments),编译器会忽略它们,不过阅读代码的人可能觉得有用。在 Rust 中,惯用的注释样式是以两个斜杠开始注释,并持续到本行的结尾。也可以包含一个可选的 else 表达式来提供一个在条件为假时应当执行的代码块,这里我们就这么做了。分编程语言的基本组成部分。

2024-02-29 09:39:55 292

原创 Rust从入门到实战系列二十八:具有返回值的函数

函数 plus_one 的定义说明它要返回一个 i32 类型的值,不过语句并不会返回值,使用单位类型 () 表示不返回值。在 Rust中,函数的返回值等同于函数体最后一个表达式的值。five 函数的返回值是 5,所以返回值类型是 i32。注意,也指定了函数返回值的类型,就是 −> i32。但如果在包含 x + 1 的行尾加上一个分号,把它从表达式变成语句,我们将看到一个错误。其次,five 函数没有参数并定义了返回值类型,不过函数体只有单单一个 5 也没有分号,因为这是一个表达式,我们想要返回它的值。

2024-02-29 09:35:31 139

原创 Rust从入门到实战系列二十七:语句和表达式

表达式会计算出一个值,并且你将编写的大部分 Rust 代码是由表达式组成的。中的 6 是一个表达式,它计算出的值是 6。目前为止,我们提到的函数还不包含结尾表达式,不过你已经见过作为语句一部分的表达式。因为 Rust 是一门基于表达式(expression-based)的语言,这是一个需要理解的(不同于其他语言)重要区别。其他语言并没有这样的区别,所以让我们看看语句与表达式有什么区别以及这些区别是如何影响函数体的。是一个代码块,它的值是 4。如果在表达式的结尾加上分号,它就变成了语句,而语句不会返回值。

2024-02-29 09:32:22 122

原创 Rust从入门到实战系列二十六:函数

我们可以定义为拥有 参数(parameters)的函数,参数是特殊变量,是函数签名的一部分。技术上讲,这些具体值被称为参数(arguments),但是在日常交流中,人们倾向于不区分使用 parameter 和 argument 来表示函数定义中的变量或调用函。在函数签名中,必须声明每个参数的类型。这是 Rust 设计中一个经过慎重考虑的决定:要求在函数定义中提供类型注解,意味着编译器再也不需要你在代码的其他地方注明类型来指出你的意图。你已经见过语言中最重要的函数之一:main 函数,它是很多程序的入口点。

2024-02-29 09:29:34 145

原创 Rust从入门到实战系列二十五:访问数组元素

当尝试用索引访问一个元素时,Rust 会检查指定的索引是否小于数组的长度。如果索引超出了数组长度,Rust 会 panic,这是 Rust 术语,它用于程序因为错误而退出的情况。在很多底层语言中,并没有进行这类检查,这样当提供了一个不正确的索引时,就会访问无效的内存。第九章会讨论更多 Rust 的错误处理。如果您使用 cargo run 运行此代码并输入 0、1、2、3 或 4,程序将在数组中的索引处打印出相应的值。在这个例子中,叫做 first 的变量的值是 1,因为它是数组索引 [0] 的值。

2024-02-29 09:26:23 81

原创 Rust从入门到实战系列二十四:复合类型

当你想要在栈(stack)而不是在堆(heap)上为数据分配空间(第四章将讨论栈与堆的更多内容),或者是想要确保总是有固定数量的元素时,数组非常有用。没有任何值的元组 () 是一种特殊的类型,只有一个值,也写成 ()。与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,Rust 中的数组长度是固定的。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。可以像这样编写数组的类型:在方括号中包含每个元素的类型,后跟分号,再后跟数组元素的数量。

2024-02-29 09:23:59 280

原创 Rust从入门到实战系列二十三:数据类型

第九章”panic!每一个变体都可以是有符号或无符号的,并有一个明确的大小。不过,” 字符” 并不是一个 Unicode 中的概念,所以人直觉上的 ” 字符”可能与 Rust 中的 char 并不符合。无符号的变体可以储存从 0 到 2n- 1 的数字,所以 u8 可以储存从 0 到 28 - 1 的数字,也就是从 0 到 255。请注意可以是多种数字类型的数字字面值允许使用类型后缀,例如 57u8 来指定类型,同时也允许使用 _ 做为分隔符以方便读数,例如1_000,它的值与你指定的 1000 相同。

2024-02-29 09:19:14 423

原创 Rust从入门到实战系列二十二:常量

类似于不可变变量,常量 (constants) 是绑定到一个名称的不允许改变的值,不过常量与变量还是有一些区别。在下一部分,” 数据类型” 中会介绍类型和类型注解,现在无需关心这些细节,记住总是标注类型即可。常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。最后一个区别是,常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出的值。然后,在内部作用域内,第三个 let 语句也隐藏了 x,将之前的值乘以 2,x 得到的值是 12。

2024-02-29 09:09:52 222

原创 Rust从入门到实战系列二十一:关键字

不过,你仍然可以使用可变变量。接着,在新建的 variables 目录,打开 src∕main.rs 并将代码替换为如下代码,这些代码还不能编译,我们会首次检查到不可变错误(immutability error)。在尝试改变预设为不可变的值时,产生编译时错误是很重要的,因为这种情况可能导致 bug。如果一部分代码假设一个值永远也不会改变,而另一部分代码改变了这个值,第一部分代码就有可能以不可预料的方式运行。变量和可变性 57Rust 编译器保证,如果声明一个值不会变,它就真的不会变,所以你不必自己跟踪它。

2024-02-29 09:03:26 92

原创 Rust从入门到实战系列二十:处理无效输入

Err 值不能匹配第一个 match 分支的 Ok(num) 模式,但是会匹配第二个分支的 Err(_ ) 模式:_ 是一个通配符值,本例中用来匹配所有 Err 值,不管其中有何种信息。本项目通过动手实践,向你介绍了 Rust 新概念:let、match、函数、使用外部 crate 等等,接下来的几章,你会继续深入学习这些概念。这个 Ok 值与match 第一个分支的模式相匹配,该分支对应的动作返回 Ok 值中的数字 num,最后如愿变成新创建的guess 变量。此时此刻,你顺利完成了猜猜看游戏。

2024-02-29 08:52:26 83

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除