rust编程-通用编程概念(chapter 3.2 3.3 数据类型和函数)

news2025/7/20 9:31:14

目录

2. 数据类型

2.2 复合类型

3. 函数


2. 数据类型

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

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

例如:

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

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

# cargo build
   Compiling 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 type

For 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; // f64

    let 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个3
    let 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 run
   Compiling 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 semicolon

For more information about this error, try `rustc --explain E0308`.
error: could not compile `functions` due to previous error

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

关于作者:

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/35888.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计——基于SpringBoot框架的网上购书系统的设计与实现

文章目录前言一、背景及意义选题背景选题目的二、系统设计主要功能运行环境三、系统实现部分页面截图展示部分代码展示四、源码获取前言 提示:这里可以添加本文要记录的大概内容: 二十一世纪是网络化,信息化的时代,为了满足广大…

Linux的子shell

linux运行一个shell脚本,其本身能启动它自己的子进程。 一般来说,脚本里的一个外部命令能生成出一个紫禁城,而Bash内建命令却不这样。 将一组命令放在圆括号里执行,形成一个命令列表连续执行。在圆括号里的命令会在一个子shell里…

【算法面试题汇总】LeetBook列表的算法面试题汇总---排序与检索题目及答案

整理不易留个小心心呗🥰 如果有更好的或者是我有错的地方还请各位大佬指出哦 有些是copy的还望不要介意 排序与检索最大数摆动排序Ⅱ寻找峰值寻找重复数最大数 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组…

【实验记录1】行人重识别

使用ResNet50训练Market15010x00参考0x01准备数据集0x02搭建模型ResNet500x03test0x04可视化结果0x00参考 ⭐️郑哲东博士的GitHub 从零开始行人重识别-知乎 全篇对于上手person ReId 具有重要意义 环境: torch_version1.13.0cu117 python_version3.8.13 torch_ver…

CentOS7下Redis7安装

​欢迎光临我的博客查看最新文章: https://river106.cn 目前Redis的最新稳定版本已到7.0,本文介绍redis-7.0.5在CentOS7.6下的安装使用。 1、下载 Redis下载地址:https://redis.io/download/,或者使用命令直接下载: cd /opt/so…

序列化、反序列化

一、序列化、反序列化概念 序列化(Serialization)是一种将对象以一连串的字节描述的过程,将程序中的对象,放入硬盘(文件)中保存就是序列化,如果不存放在磁盘中,而是一直存放在内存中,会增大内存的消耗;序列化就是将对象的状态信息转换为可以存储或传输的形式的过程;…

Scrapy基本概念——Item Pipeline

一、Item Pipeline介绍 蜘蛛抓取的每一个Item都会被发送到Item Pipeline。根据ITEM_PIPELINES的优先级设置,不同的Item Pipeline依次处理每一个Item,最后可删除该Item不做处理,也可将该Item发送到下一个Item Pipeline。Item Pipeline的主要用…

基于8086的压力检测器设计(Proteus8仿真)

一、实验名称 基于 proteus 设计压力检测计 二、实验目的  深刻理解并掌握基于 8086 处理器的系统工程的工作原理和流程;  深刻理解并掌握 8086 处理器的工作原理、引脚功能;  深刻理解并掌握压力传感器件 MPX4115 的工作原理、引脚功能&#x…

C++:函数指针进阶:看完还不用std::function来捶我

1:函数指针的背景 我们先简单聊一下函数指针的背景,具体使用请参考我的这篇博客 C :函数: 函数指针_hongwen_yul的博客-CSDN博客 假设现在有这样一段代码:C/C中可以使用指针指向一段代码,这个指针就叫函…

【季报分析】百度2022年Q3:逆势而上

11月22日,百度(09888.HK)发布了2022年第三季度的业绩报告,尽管面对疫情不断侵扰、外部环境压力带来的诸多挑战,百度在Q3依然取得了相当不错的财务数据,尤其是在自动驾驶、智能硬件方面的表现尤为突出&#…

【Linux】缓冲区

目录🌈前言🌷1、缓冲区🍡1.1、缓冲区的理解🍢1.2、缓冲区在哪里?🍣1.3、缓冲区的刷新策略🍣1.4、模拟实现C库函数🌸2、标准输出流与错误流的区别🍤2.1、概念&#x1f365…

微客云升级会员制度

会员制度 会员制度是一种人与人或组织与组织之间进行沟通的媒介,它是由某个组织发起并在该组织的管理运作下,吸引客户自愿加入,目的是定期与会员联系,为他们提供具有较高感知价值的利益包。 Part 1 会员制度 建立长期稳定的客…

Python测试框架之Pytest基础入门

Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. 通过官方网站介绍…

Vue子组件传自定义事件给父组件

我们知道组件之间是不能够进行通信的,都是相互独立的,你用不了我的状态和方法,我也用不了你的,那如何实现通信呢,可以间接实现; 实现父组件和子组件的通信: 子组件想用父组件的状态需要父组件…

Apache ShardingSphere(二) 基本使用

文章目录二 ShardingSphere JDBC 基本使用2.1 ShardingSphere JDBC 水平分表2.1.1 案例入门2.1.2 解读配置文件2.1.3 其他测试2.1.4 延伸问题2.2 ShardingSphere JDBC 水平分库2.2.1 案例入门2.2.2 解读配置文件2.1.3 其他测试2.3 ShardingSphere JDBC 广播表2.3.1 基本案例入门…

矩阵链相乘(动态规划)

【问题描述】给定n个矩阵M1,M2...MnM_1,M_2...M_nM1​,M2​...Mn​,他们的维数分别是r1∗c1,r2∗c2...rn∗cnr_1*c_1,r_2*c_2...r_n*c_nr1​∗c1​,r2​∗c2​...rn​∗cn​,要求使用【动态规划】的策略求解矩阵连乘的最优计算代价(总乘法次数最少)。题目…

Docker 学习视频集 bilibili

1.什么是Docker_哔哩哔哩_bilibili 2.Docker的安装_哔哩哔哩_bilibili 3.镜像、容器和仓库_哔哩哔哩_bilibili 4.在容器中部署一个应用_哔哩哔哩_bilibili 5.将容器保存成镜像成片_哔哩哔哩_bilibili 6.使用Dockerfile构建镜像1_哔哩哔哩_bilibili 7.导入导出镜像_哔哩哔…

vscode配合gitee同步云设置

更换开发设备后,新安装的vscode软件,是没有原先的配置的,诸如快捷键,快捷代码段生成、安装的各个插件,插件的配置等都木大了,开发起来会很别扭,网上最多的就是去安装一个叫做Settings Sync的插件…

springcloud五大核心部件

springcloud五大核心部件 一、springcloud介绍 springcloud是微服务的集大成者,将一系列的组件进行了整合。基于springboot构建 ,可以快速配置常用模块并构建庞大的分布式系统。 二、具体业务分析 我们举一个例子来进行业务场景分析 假设现在开发一…

Websocket学习

参考:http://www.mydlq.club/article/86/ 这里写目录标题一、WebSocket 简介二、WebSocket 特点三、为什么需要 WebSocket四、WebSocket 连接流程五、WebSocket 使用场景六、使用案例1.提醒客户端有新订单2.客户端交互一、WebSocket 简介 WebSocket 是一种基于 TCP…