文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Rust 劝退系列 之基本数据类型

2024-12-03 06:00

关注

大家好,我是站长 polarisxu。

这是 Rust 劝退系列的第 4 个教程,探讨 Rust 中的基本数据类型,或叫标量类型(scalar type)。

Rust 和 Go 一样,都是静态类型语言,这表示每个变量的类型必须明确。和 Go 类似,大多数情况下,Rust 编译器能够推断出某个值的类型,不需要我们显示指定,写起来有点类似于弱类型似语言。但有些情况下,必须明确告知编译器我们使用什么类型,在 Rust 中,这叫 「类型注解」(type annotations)。

对于类型注解,看一个常见的例子:

  1. let guess = "42".parse().expect("Not a number!"); 

这是将字符串 "42" 转为数字 42。在 Go 语言中,一般这么做:

  1. guess, err := strconv.Atoi("42"
  2. if err != nil { 
  3.   panic(err) 

但上面的 Rust 代码会报错:

  1. error[E0282]: type annotations needed 
  2.  --> src/main.rs:2:9 
  3.   | 
  4. 2 |     let guess = "42a".parse().expect("Not a number!"); 
  5.   |         ^^^^^^ consider giving `guess` a type 

这和 Go 还是不太一样。Go 中很多时候,数值类型会是 int。

为了修复这个问题,我们需要为 number 指定一个类型,比如 u32。

  1. let guess: u32 = "42".parse().expect("Not a number!"); 

吐槽:在 Rust 中,类型注解和 Go 中一样,放在变量后面。但 Rust 中变量和类型直接非得加一个冒号(:),而且一般冒号紧跟着变量名(rustfmt 的建议)。不知道冒号有啥特殊需要?!

Rust 内置如下基本数据类型:

01 整数类型

将整数类型整理为一张表,如下:(用 Go 语言对应的类型作对比)

长度 有符号 无符号 Go 有符号 Go 无符号
8-bit i8 u8 int8 uint8
16-bit i16 u16 int16 uint16
32-bit i32 u32 int32 uint32
64-bit i64 u64 int64 uint64
128-bit i128 u128 - -
arch isize usize int uint

吐槽:有时候 Rust 真的很节省,int、uint 直接省略为 i、u,function 省略为 fn。但有时候又很繁琐(不简洁),比如前面说到的变量和类型之间的冒号。。。

这里用 u、i 的形式,也需要一段时间适应。。。

两点说明:

在 Go 中,整型变量默认类型是 int,以下代码可以证明这一点:

  1. x := 32 
  2. fmt.Printf("%T\n", i) 
  3. // 输出:int 

那 Rust 中默认是什么类型呢?

我想在 Rust 中找到一种办法,打印变量类型,网上找到了这样的办法(有点挫):

  1. // 打印变量类型的函数。该函数看不懂先放着。 
  2. fn print_type_of(_: &T) { 
  3.   println!("{}", std::any::type_name::()) 
  4.  
  5. fn main() { 
  6.     let x = 32; 
  7.     print_type_of(&x); 
  8.    // 输出:i32 

可见 Rust 中整型变量默认类型是 i32(即使在 64 位机器上,也是 i32)。这一定程度上说明,在 Go 中,整数一般建议用 int 类型;而 Rust 中,一般建议用 i32 类型。(所以,为什么开头的 parse 不能默认推断为 i32 类型呢?怕溢出?)

更智能的类型推断

上文说 Rust 和 Go 一样,支持类型推断。不过 Rust 的推断更智能,怎么个智能法?看下面的代码:

  1. // 打印变量类型的函数 
  2. fn print_type_of(_: &T) { 
  3.     println!("{}", std::any::type_name::()) 
  4.  
  5. fn main() { 
  6.     let x = 32; 
  7.     let y: i8 = x; 
  8.     print_type_of(&x); 
  9.     print_type_of(&y) 

根据上面的讲解,x 应该是默认类型:i32。但实际上,x 和 y 的类型都是 i8。也就是说,因为 x 的类型没有显示的指定(类型注解),Rust 编译器会根据上下文(实际上是 let y: i8 = x 这句)推断出 x 的类型应该和 y 一致,即 i8。

在 Go 中,int8 和 int 是不会进行隐式转换的,Rust 也一样,必须进行显示转换。但 Rust 的智能类型推断,可以让开发者少写类型转换的代码。

比如上面代码,在 Go 语言中是行不通的:

  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.  
  6. func main() { 
  7.  x := 32 
  8.  var y int8 = x 
  9.  fmt.Printf("%T\n", x) 
  10.  fmt.Printf("%T\n", y) 

会报错:

  1. cannot use x (type intas type int8 in assignment 

也就是说,Go 中的类型推断不会考虑上下文,因此没有 Rust 智能。

因为编译器的强大,VSCode 中(安装 rust-analyzer)会有类型提示,这样上面的 print_type_of 函数也不需要了。做了一个动图,注意上面 x 的类型变化:

此外,isize 和 usize 类型一般用作某些集合的索引,以后文章会看到。

关于各种类型的表示范围我列出了,因为这个系列不是为无编程经验的人准备的。这个系列更多是为 Go 爱好者准备的 Rust 教程,因此和 Go 一致的地方可能不会讲。

02 浮点类型

和 Go 一样,Rust 也有两种浮点数类型:f32 和 f64,对应 Go 中的 float32 和 float64。和 Go 一样,默认类型是 f64,可以通过类型注解指定具体的浮点类型。

  1. let x = 2.0; // 默认是 f64 

一般地,整数类型和浮点类型都成为数值类型。

数值类型有一些共同的东西。比如都支持基本的数学运算。此外,除了通过类型注解指定类型,数值类型还可以在字面值后面带上类型后缀指定类型,比如:

  1. let x = 2.0f32; // f32 类型 
  2. let y = 32i64; // i64 类型 

03 布尔型

和 Go 语言一样,Rust 中的布尔类型使用 bool 表示(咋没用 b、bl 之类的缩写呢?哈哈哈)。有两个可能的值:true 和 false。

  1. fn main() { 
  2.     let t = true
  3.  
  4.     let f: bool = false; // 显式指定类型注解 

04 字符型

Rust 中的 char 表示字符类型,是 Rust 的基本类型,字面值由单引号指定。

  1. let a = 'a'
  2. let b = '中'
  3. let c = '🤣'

可见,Rust 中的 char 类型和 Go 中的 rune 一样,表示的是 Unicode 码点,占 4 个字节。

因为 Rust 中的字符串很复杂,而且不是基本类型,因此留在以后讲解。

05 小结

本文介绍了 Rust 中的四种基本数据类型:整型、浮点型、布尔型和字符型。其中,浮点型、布尔型和字符型分别对应 Go 中的浮点型、布尔型和 rune 类型,但整型,Go 和 Rust 有些许不一样,上文已经详细介绍了。此外,Go 中复数也是基本数据类型:complex64 和 complex128,而 Rust 中没有,复数通过第三方库实现,比如:https://crates.io/crates/easy_complex。

此外,你可能会说 Go 中还有一个基本类型:byte,而 Rust 没有。其实 Go 中的 byte 只是 uint8 的别名。另外,string 在 Go 中是基本数据类型,而在 Rust 中不是。

本文转载自微信公众号「polarisxu」,可以通过以下二维码关注。转载本文请联系polarisxu公众号。

 

来源:polarisxu内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯