当前位置: 首页 > 科技观察

Rust劝导系列基础数据类型

时间:2023-03-12 17:55:32 科技观察

大家好,我是站长polarisxu。这是Rust退出系列的第4篇教程,探索Rust中的原始数据类型或标量类型。Rust和Go一样,是一种静态类型语言,这意味着每个变量的类型必须是明确的。与Go类似,在大多数情况下,Rust编译器无需我们显式指定它就可以推断出值的类型,这有点像弱类型语言。但在某些情况下,我们必须明确地告诉编译器我们使用什么类型。在Rust中,这称为“类型注释”。对于类型注释,请参见一个常见示例:letguess="42".parse().expect("Notanumber!");这会将字符串“42”转换为数字42。在Go语言中,通常这样做:guess,err:=strconv.Atoi("42")iferr!=nil{panic(err)}但上面的Rust代码会报错:error[E0282]:typeannotationsneeded-->src/main.rs:2:9|2|letguess="42a".parse().expect("Notanumber!");|^^^^^^considergiving`guess`atype这和围棋还是不太一样。在Go中很多时候,数值类型都是int。为了解决这个问题,我们需要为数字指定一个类型,比如u32。letguess:u32="42".parse().expect("Notanumber!");吐槽:在Rust中,和在Go中一样,类型注解是放在变量之后的。但是Rust中的变量和类型直接要加冒号(:),一般冒号后面跟变量名(rustfmt的建议)。不知道大肠有什么特殊需求?!Rust内置了以下基本数据类型:整数类型包括整数:i8、i16、i32、i64、i128、isize无符号整数:u8、u16、u32、u64、u128、usize浮点型:f32、f64布尔型:bool字符类型:char01整数类型将整数类型整理成表,如下:(与Go语言对应类型对比)LengthSignedandunsignedGoSignedGoUnsigned8-biti8u8int8uint816-biti16u16int16uint1632-biti32u32int32uint3264-biti64u64int64uint64128-biti128u128--archisizeusizeintuint直接省略是i,u,函数省略是fn。但是有时候很繁琐(不简洁),比如上面说的变量和类型之间的冒号。..这里使用的是u和i的形式,需要一段时间来适应。..两种解释:Go中没有128位整数。isize和usize对应Go中的int和uint。它们的长度取决于运行程序的计算机体系结构:在64位体系结构上它们是64位的,在32位体系结构上它们是32位的。在Go中,整型变量的默认类型是int。下面的代码可以证明这一点:x:=32fmt.Printf("%T\n",i)//Output:intRust中的默认类型是什么??我想在Rust中找到一种打印变量类型的方法,在网上找到了这个方法(有点郁闷)://Functiontoprintvariabletype。如果您不了解此功能,请不要管它。fnprint_type_of(_:&T){println!("{}",std::any::type_name::())}fnmain(){letx=32;print_type_of(&x);//输出:i32}可以看出,Rust中整数变量的默认类型是i32(即使在64位机器上,也是i32)。这在一定程度上说明了在Go中,整数一般推荐使用int类型;而在Rust中,一般推荐使用i32类型。(所以,为什么一开始的parse不能默认推断为i32类型?怕溢出?)但是Rust的推理更聪明,怎么算是聪明的方法呢?看下面的代码://打印变量类型的函数fnprint_type_of(_:&T){println!("{}",std::any::type_name::())}fnmain(){letx=32;lety:i8=x;print_type_of(&x);print_type_of(&y)}根据上面的解释,x应该是默认类型:i32。但实际上,x和y都是i8类型。也就是说,因为没有明确指定x的类型(类型注解),Rust编译器会根据上下文(实际上是语句lety:i8=x)推断出x的类型应该和y一致,即i8。在Go中,int8和int是不会隐式转换的,Rust也是一样,必须显式转换。但Rust的智能类型推断让开发者可以编写更少的类型转换代码。例如,上面的代码在Go语言中不起作用:packagemainimport("fmt")funcmain(){x:=32varyint8=xfmt.Printf("%T\n",x)fmt.Printf("%T\n",y)}会报错:cannotusex(typeint)astypeint8inaassignment也就是说Go中的类型推断不考虑上下文,所以没有Rust的智能。由于编译器的强大,在VSCode(安装rust-analyzer)中会有类型提示,所以不需要上面的print_type_of函数。做了个动图,注意上面x的类型变化:另外isize和usize这两个类型一般是作为某些集合的索引,在以后的文章中会看到。我列出了各种类型的表示范围,因为这个系列不适合没有编程经验的人。本系列更多的是针对Go爱好者的Rust教程,所以与Go一致的地方可能不会涉及到。02浮点类型和Go一样,Rust也有两种浮点类型:f32和f64,分别对应Go中的float32和float64。和Go一样,默认类型是f64,具体的浮点类型可以通过类型注解指定。letx=2.0;//默认为f64一般整型和浮点型都变成数值型。数字类型有一些共同点。例如,支持基本的数学运算。另外,数值类型除了可以通过类型注解来指定类型外,还可以在字面值后加上类型后缀来指定类型,例如:letx=2.0f32;//f32typelety=32i64;//i64type03布尔类型是和Go语言一样,Rust中的布尔类型用bool来表示(为什么不用b、bl之类的缩写呢?哈哈哈)。有两个可能的值:true和false。fnmain(){lett=true;letf:bool=false;//显式指定类型注解}04Rust中字符char表示字符类型,是Rust的基本类型,字面值用单引号指定分数。leta='a';letb='in';letc='🤣';可以看出Rust中的char类型和Go中的rune一样,代表一个Unicode码位,占用4个字节。因为Rust中的字符串很复杂而不是原始类型,所以我把它们留到以后再说。05总结本文介绍了Rust中的四种基本数据类型:整数、浮点数、布尔值和字符。其中,浮点型、布尔型和字符型分别对应Go中的浮点型、布尔型和符文型,但整型、Go和Rust略有不同,上面已经详细介绍过了。另外,复数在Go中也是基本数据类型:complex64和complex128,但在Rust中不是。复数是通过第三方库实现的,例如:https://crates.io/crates/easy_complex。此外,您可能会争辩说Go中有一个原始类型:byte,而Rust没有。实际上Go中的byte只是uint8的别名。此外,字符串在Go中是原始数据类型,但在Rust中不是。本文转载自微信公众号「polarisxu」,可通过以下二维码关注。转载本文请联系polarisxu公众号。