rust编程-通用编程概念(chapter 3.2 3.3 数据类型和函数)
创始人
2024-02-15 16:28:28

目录

2. 数据类型

2.2 复合类型

3. 函数


2. 数据类型

Rust中的所有值都是有特定数据类型的,rust是强类型语言,也是静态类型语言(编译器类型必须确定)。

编译器可以根据值来进行类型推断,但对有歧义的,必须指定特定的类型。

例如:

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

如果不指定guess类型,编译器报错如下:

# cargo buildCompiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations)
error[E0282]: type annotations needed--> src/main.rs:2:9|
2 |     let guess = "42".parse().expect("Not a number!");|         ^^^^^ consider giving `guess` a typeFor more information about this error, try `rustc --explain E0282`.
error: could not compile `no_type_annotations` due to previous error

2.1 标量类型

标量指单值类型,rust有四种主要的标量类型如下:

  • 整型

无小数部分的数字就是整型,rust支持下表的整型类型:

长度

有符号

无符号

8位

i8

u8

16位

i16

u16

32位

i32

u32

64位

i64

u64

128位

i128

u128

特定架构

相关

isize

usize

每类长度的整型都分为有符号和无符号类型,有符号类型可以是负值。整型在内存中以补码的格式存储。

isize和usize类型的大小依赖于处理器硬件架构,在64位架构上是64位长,在32位架构上是32位长。isize和usize主要应用场景是集合的索引。

Rust编程对整型字面常量的书写方式支持后缀标识类型 ,例如:57u8,表示u8类型的57整型值;支持单下划线_ 用来分割数字,例如:1_000,表示数字1000;支持前缀标识进制 ,例如:0o89,表示8进制数字89。如下表:

Number literals

Example

Decimal

98_222

Hex

0xff

Octal

0o77

Binary

0b1111_0000

Byte (u8 only)

b'A'

  • 浮点型

Rust有两种浮点类型,f32和f64, 分别是32位和64位,浮点数都是有符号的。单精度的f32和双精度的f64的浮点型,在内存中表示格式都采用IEEE754格式。

fn main() {let x = 2.0; // f64let y: f32 = 3.0; // f32
}
  • boolean类型

如大多数编程语言,Rust boolean类型有true和false 两个值,在存储上,rust使用1个字节。定义如下:

fn main() {let t = true;let f: bool = false; // with explicit type annotation
}
  • 字符类型

Rust用单引号指定字符字面量,用双引号指定字符串字面量。

Rust的char类型大小为4个字节, 表示Unicode标量值,可以表示ASCII以及ASCII之外的多种字符。例如:重音字母、中文、日文、韩文,emoji等,都是Rust中的有效字符值。Unicode标量值范围从U+0000到U+D7FF和U+E000到U+10FFFF包括在内。然而,“字符”在Unicode中并不是一个真正的概念,因此您对“字符”的直觉认识可能与Rust中的字符不匹配。我们将在第8章的“使用字符串存储UTF-8编码文本”中详细讨论这个主题。

fn main() {let c = 'z';let z = 'ℤ';let heart_eyed_cat = '😻';
}

2.2 复合类型

Rust有两种基本的复合类型-元组和数组 ,复合类型将多元素值聚合成单类型变量。

  • 元组(tuple)类型

元组将一组逗号间隔、括号括住的多个值聚合为单个元组类型值。元组中,每个位置可以有单独的类型,且元组大小已经定义不能改变(扩大或缩小)。

fn main() {// let tup: (i32, f64, u8) = (500, 6.4, 1);let tup = (500, 6.4, 1);let (x, y, z) = tup;let five_hundred = x.0;let six_point_four = x.1;println!("The value of y is: {}", y);
}

元组类型中的值访问,有以下两种方式:

1)可以用模式析取 访问,如上述x,y,z来将单元组中的元素值取出来赋值。

2)利用元组的索引 访问,如上述代码。

  • 数组类型

数组是一个包含相同类型值 的复合类型,其中每个元素的类型必须相同,且Rust的数组大小是固定的。

fn main() {let a = [1, 2, 3, 4, 5];let months = ["January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December"];
}

Rust的数组分配在栈上(详见第4章),rust标准库中有vector类型,大小可以动态增长和缩小(详见第8章),vector类型使用更灵活好用。

Rust数组是固定不可变的,在需要不变的常量列表时,rust数组也比较有用。

Rust数组定义和使用方式如下:

fn main() {let a: [i32; 5] = [1, 2, 3, 4, 5]; // 定义5长度的i32类型的数组let b = [3; 5];    // 定义5长度的默认整型类型(i32)的数组,初始化为5个3let first = a[0];  // 数组访问方式同C/C++语言let fifth = b[4];
}

有关数组越界:

不同于C/C++语言,Rust在运行时会自动检查数组越界,并报错产生panic,程序退出。这是Rust内存安全原则之一。 第9章节会介绍Rust的错误处理。

use std::io;fn main() {let a = [1, 2, 3, 4, 5];println!("Please enter an array index.");let mut index = String::new();io::stdin().read_line(&mut index).expect("Failed to read line");let index: usize = index.trim().parse().expect("Index entered was not a number");let element = a[index];println!("The value of the element at index {} is: {}",index, element);
}

上述代码,运行时输入大于4的数字,会导致rust程序panic退出。

3. 函数

Rust函数用关键词fn 定义,后面跟一个函数名、一个括号括住的参数集合 ,花括号括住的是函数体。

在编译单元中,Rust与C语言不同的时,rust函数的调用不需要再rust函数定义的后边,也不需要提前声明rust函数。如下:

fn main() {println!("Hello, world!");another_function();
}fn another_function() {println!("Another function.");
}fn another_function(x: i32) {println!("The value of x is: {}", x);
}
  • 函数名

函数名采用snake风格的命名,即所有字母小写、用下划线分割

  • 参数

rust函数参数必须指定类型,在函数定义时需要指定类型标记。如下:

fn print_labeled_measurement(value: i32, unit_label: char) {println!("The measurement is: {}{}", value, unit_label);
}
  • 语句和表达式

函数体由一系列语句组成,可选地也可以以表达式结束。到目前为止,示例的函数还没有包含一个结束表达式,但已经有表达式作为语句的一部分的形式。因为Rust是一种基于表达式的语言,这是一个与其它编程语言很重要的区别。

  • 返回值

rust函数可以有返回值,返回值不需要命名,但需要用->标识符来声明返回值类型。 通过使用return关键字并指定一个值,可以提前从函数返回,但大多数函数都隐式返回最后一个表达式。如下:

fn five() -> i32 {5    // 表达式自返回值,直接隐式作为函数返回值,注意尾部不能有分号
}

如下错误 代码示例:

fn main() {let x = plus_one(5);println!("The value of x is: {}", x);
}fn plus_one(x: i32) -> i32 {x + 1;
}
cargo runCompiling functions v0.1.0 (file:///projects/functions)
error[E0308]: mismatched types--> src/main.rs:7:24|
7 | fn plus_one(x: i32) -> i32 {|    --------            ^^^ expected `i32`, found `()`|    ||    implicitly returns `()` as its body has no tail or `return` expression
8 |     x + 1;|          - help: consider removing this semicolonFor more information about this error, try `rustc --explain E0308`.
error: could not compile `functions` due to previous error

加上分号变成了一个语句,无返回值。这种情况下,语句默认是一个()表达 unit类型值,与函数定义的返回值冲突。

关于作者:

犇叔,浙江大学计算机科学与技术专业,研究生毕业,而立有余。先后在华为、阿里巴巴和字节跳动,从事技术研发工作,资深研发专家。主要研究领域包括虚拟化、分布式技术和存储系统(包括CPU与计算、GPU异构计算、分布式块存储、分布式数据库等领域)、高性能RDMA网络协议和数据中心应用、Linux内核等方向。

专业方向爱好:数学、科学技术应用

关注犇叔,期望为您带来更多科研领域的知识和产业应用。

内容坚持原创,坚持干货有料。坚持长期创作,关注犇叔不迷路

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...