变量与数据类型

news2024/12/23 16:43:03

专栏简介:本专栏作为Rust语言的入门级的文章,目的是为了分享关于Rust语言的编程技巧和知识。对于Rust语言,虽然历史没有C++、和python历史悠远,但是它的优点可以说是非常的多,既继承了C++运行速度,还拥有了Java的内存管理,就我个人来说,还有一个优点就是集成化的编译工具cargo,语句风格和C++极其相似,所以说我本人还是比较喜欢这个语言,特此建立这个专栏,作为学习的记录分享。

日常分享:每天努力一点,不为别的,只是为了日后,能够多一些选择,选择舒心的日子,选择自己喜欢的人!


目录

Rust中的变量

可变变量

不可变变量

常量

隐藏

数据类型

标量类型

整型

浮点型

布尔型

字符类型

复合类型

元组类型

数组类型

总结


Rust中的变量

相信熟悉c++或者其他编程语言的,都会很熟悉变量这个词,变量作为暂时存储数值的容器,不过在Rust中,变量默认是不可变的。这个特性和Rust的性质是有关系的。虽然说是叫变量,但是又是不可变的,这是由于一个所有权的原因,这个问题留到后面细细讲解。

可变变量

变量的声明关键字是:let

如果是要声明可变变量,则添加关键字mut.


fn main() {
    let mut rng = 10;
    println!("rng的为: {}", rng);
    rng=20;
    println!("rng的为: {}", rng);
    
}

可以看到这里变量rng的值可以再次赋值,不会出现报错。

不可变变量

不可变变量的定义就是可变变量没有mut关键字,不能二次赋值。

我们发现这里出现了报错,不允许二次对变量rcg赋值,这代表就是不可变变量。

常量

类似于不可变变量,常量 (constants) 是绑定到一个名称的不允许改变的值,不过常量与变量还是有一些区别。

首先,不允许对常量使用 mut。常量不光默认不可变,它总是不可变。声明常量使用 const 关键字而不是 let,并且 必须 注明值的类型。在下一部分,“数据类型” 中会介绍类型和类型注解,现在无需关心这些细节,记住总是标注类型即可。

常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。

最后一个区别是,常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出的值。这里和c++中的常量表达式十分相似。其实简单的说就是常量在编译时就必须获得值,而不是在运行过程中才能获得值。下面举几个例子:

const THETA_COUNT: usize =30*1024;
    println!("THETA_COUNT: {}", THETA_COUNT);

 这里定义了一个常量,是30*1024,结果运行成功,这是因为在编译时就已经计算出了确切的值,我们再看另一个例子:


fn main() {
    const THETA_COUNT2:usize=get_value_count();
    println!("THETA_COUNT2: {}", THETA_COUNT2);
}
fn get_value_count() -> usize {
    let count =30;
    return count;
}

 error[E0015]: cannot call non-const fn `get_value_count` in constants

最后结果报错,显示不能由函数转化成常量。这就是常量的特性,只能由在编译时能获的确切值的表达式组成。

隐藏

前面提到的可变变量,虽然可以二次赋值,但是需要声明是可变变量,除此之外,Rust还有一种方式可以改变变量的值——隐藏。

我们可以定义一个与之前变量同名的新变量。Rustacean 们称之为第一个变量被第二个 隐藏(Shadowing) 了,这意味着当您使用变量的名称时,编译器将看到第二个变量。实际上,第二个变量“遮蔽”了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用 let 关键字来多次隐藏。


fn main() {
    let args=10;
    println!("args: {}", args);
    let args=args*args;
    println!("args: {}", args);
    {
        let args=20;
        println!("args: {}", args);
    }
    println!("args: {}", args);
}


 这里先是将args绑定到10上,接着通过关键字let创建一个新变量args,args的值就变成100,然后在花括号创建的域内,let关键字将args创建一个新变量,赋值为20,第三个let只在域内起作用,花括号之外的的值依旧是原本的值,运行的结果:

Finished dev [unoptimized + debuginfo] target(s) in 0.29s
     Running `target/debug/Rust`
args: 10
args: 100
args: 20
args: 100

看到这里,因该有小伙伴发现隐藏和可变变量似乎一样,其实还是存在差异,隐藏是创建了一个新变量,而可变变量的数据类型是不能变得,只能由定义时的数据类型决定。


fn main() {
   let str="hello";
   let length=str.len();
   println!("length is {}",length);
   let mut buffer="Hello, world!";
   buffer=buffer.len()+2;
   println!("buffer is {}",buffer);
}


这里显示报错,所以说隐藏和可变变量的区别就是数据类型是否可以变化。

数据类型

在 Rust 中,每一个值都属于某一个 数据类型data type),这告诉 Rust 它被指定为何种数据,以便明确数据处理方式。我们将看到两类数据类型子集:标量(scalar)和复合(compound)。

Rust语言是一种静态类型(statically typed)语言,也就是说在编译时就必须知道所有变量的内型,这点和python不一样,python是动态类型语言,其内使用的所有变量不需要指明数据类型。但是一般来说,编译器是可以推断出变量的数据类型,但是如果数据类型转换过于复杂,那就需要你去注释。
 

fn main(){

let sm=String::from("hello");

let num:usize=sm.parse().expect("not number");

println!("{}",num);

}

 这里的num变量的数据类型必须标注,如果不标注就无法编译通过,这也就再次证明了静态型语言的特点。

标量类型

在高中物理中有提到过标量和矢量,当时的标量是指一个没有方向只有大小的值,但是,这里的标量指的是单独的一个变量。用官方语言来解释就是:标量scalar)类型代表一个单独的值。。

Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。

整型

整数是一个没有小数的数字他分为无符号整型和有符号整型。

长度有符号无符号
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize

 每一个变体都可以是有符号或无符号的,并有一个明确的大小。有符号无符号 代表数字能否为负值,换句话说,这个数字是否有可能是负数(有符号数),或者永远为正而不需要符号(无符号数)。

每一个有符号的变体可以储存包含从 -(2n - 1) 到 2n - 1 - 1 在内的数字,这里 n 是变体使用的位数。所以 i8 可以储存从 -(27) 到 27 - 1 在内的数字,也就是从 -128 到 127。无符号的变体可以储存从 0 到 2n - 1 的数字,所以 u8 可以储存从 0 到 28 - 1 的数字,也就是从 0 到 255。

另外,isizeusize 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的,32 位架构上它们是 32 位的。

Rust的默认类型为i32,当你不知道使用什么类型的时候,就是用默认的数据类型。

浮点型

和其他语言也一样,Rust也有浮点数,只不过不像c++那样分为float和double两种类型,但是也是由双精度(f64)和单精度(f32)两种类型组成。Rust默认的是64位。


fn main() {
    let x=45.6;
    let y:f32=44.6;
    println!("x:{},y:{}",x,y);
 }
 
 
 

 浮点数采用 IEEE-754 标准表示。f32 是单精度浮点数,f64 是双精度浮点数。

布尔型

和C++语言一样,Rust也有布尔类型,true,false。数值类型是bool.


fn main() {
   let flag=true;
   let flags:bool = false;
   
 }

 布尔类型主要场景还是用在控制流方面。作为一个判断条件。

字符类型

Rust语言的char类型和其他语言一样,但是优点就是通用性比较好,就连一些表情都是可以进行存储的。


 
fn main() {
  let c='c';
  println!("c is {}",c);
  let a='🙍';
  println!("a is {}",a);
    
}

Rust语言的cahr类型的大小为四个字节,并代表一个Unicode标量值。比其他语言使用ASCII表示的内容多。所以这也是Rust的一个优点。

复合类型

复合类型就是指多个值合成一个复合类型。Rust中有元组和数组两种符合类型。

元组类型

学习过python的应该都知道,元组是一种将多个其他类型的值组合成一个复合类型的主要方式。元组的特性就是长度不能改变,一旦定义,就不能再更改元组的长度。注意,这里的元组和Python中的元组定义不一样。这里只是说元组的长度不变。

fn main() {
  let tup:(f32,f64,i32)=(0.9,3.42,20);
    
}

tup变量绑定到在整个元组上, 元组是一个复合函数,我们可以用模式匹配来进行获得元组中的值,模式匹配后面会更详细的介绍,这里就只是使用。

 
fn main() {
  let mut tup:(f32,f64,i32)=(0.9,3.42,20);
  //tup.1=0.8;
  let (x,y,z)=tup;
  println!("{} {} {}",x,y,z);   
}

这里使用的方法是解构方法。

除了解构方法,还有一种方式就是索引。不过和其他语言不同的是,不再需要[]号来存放下标。


fn main() {
  let tup:(i32,f32,usize) =(32,34.8,89);
  println!("The first number is {}",tup.0);
  println!("The second number is {}",tup.1);
  println!("The thrid number is {}",tup.2);
}

上面说的,元组的值可以改变,不过只有定义元组为可变变量时,才能够改变元组的值。这里我来举个例子。


 
fn main() {
  let mut rng:(i32,i64,isize)=(23,34,90);
  rng.1=30;
  println!("{},{},{}",rng.0,rng.1,rng.2);  
}

注意: 不带任何值的元组有个特殊的名称,叫做 单元(unit) 元组。这种值以及对应的类型都写作 (),表示空值或空的返回类型。如果表达式不返回任何其他值,则会隐式返回单元值。

数组类型

另一个包含多个值的方式是 数组array)。与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,Rust 中的数组长度是固定的。

fn main() {
  let arr=[1,2,3,4,5,6,7,8,9,10 ,10,11,12,13,14,15,16,17];
}

 数组的空间是在栈上开辟的,他的使用主要就是在确定好元素的个数,数据类型的时候用比较好。其他的时候,用Vector比较好。这个我们放在后面讲解,学习过c++的应该知道这个。下面我们来看一下数组的定义有几种方式以及如何去访问。

fn main() {
  let arr=[1,2,3,4,5,6,7,8,9,10 ,10,11,12,13,14,15,16,17];//传统的定义
  println!("{},{},{},{}",arr[0],arr[1],arr[2],arr[3]);
  let arr1:[i32;5]=[1,2,3,4,5]; //声明5个i32数据类型的数组
  println!("{},{},{},{}",arr1[0],arr1[1],arr1[2],arr1[3]);
  let arr2=[3;5]; //创建5个数据的数组,且每个元素都是3; 3为数组起始值,5为个数.
  println!("{},{},{}",arr1[0],arr1[1],arr1[2]);

}

 

总结

本节的内容就到此结束了,这届主要讲的就是Rust中的变量以及一些数据类型,这一节的难度不是很大,只要认真看,很快就能学会。所以,这里就不过多介绍了,我们下节见!

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

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

相关文章

互联网未来信任锚点,后量子计算标准与迁移势在必行

作者 | 宋慧 出品 | CSDN 云计算 图片 | 视觉中国 IT、数字化正在深刻改变和加速全行业的效率与创新。不过,互联网的信息通信安全基石——密码学技术仍在使用第一代公钥密码算法,而随着量子计算的产生发展,以离散对数和大数分解这类等价的数…

深入理解网络通信和TCP、IP协议-01

1、网络协议 计算机网络是什么? 随着计算机技术发展,计算机的体积和价格都在下降,之前计算机多用于研究机构,现 阶段逐步进入一般的公司用于办公。原来计算机之间传输数据需要通过软盘等第三方存储介 质进行转存,人们…

【CXL】CXL ATS 介绍

🔥点击查看精选 CXL 系列文章🔥 🔥点击进入【芯片设计验证】社区,查看更多精彩内容🔥 📢 声明: 🥭 作者主页:【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

《代码随想录》专题:二叉树的遍历

0、二叉树的遍历方式总结 二叉树主要有两种遍历方式 深度优先遍历:先往深走,遇到叶子节点再往回走。广度优先遍历:一层一层的去遍历。 从深度优先遍历和广度优先遍历进一步拓展,才有如下遍历方式 深度优先遍历 前序遍历&#xff…

【网络编程】网络编程核心概念与模式

配套环境 vscode、gcc、ubuntu22.04 概念描述 网络编程的本质 使用操作系统提供的接口函数,使得应用程序具备收发网络数据的能力。 网络接口在代码层面是操作系统提供的函数 应用程序通过网络接口使用操作系统的联网能力 网络编程核心概念 协议:为进…

STM32——led灯的点亮+闪烁+流水灯的实现

文章目录 一、LED点亮1.原理2.寄存器方式--代码3.库函数--代码4.结果展示 二、LED闪烁三、LED流水灯1.代码2.结果展示 一、LED点亮 1.原理 其方式有两种一种是寄存器方式一种是库函数方式,但其原理都是一样的。如原理图所示,与LED相连接的IO口置低电平…

HTML学习 第一部分(前端学习)

参考学习网站: 网页简介 (w3schools.com) 我的学习思路是:网站实践视频。 视频很重要的,因为它会给你一种开阔思路的方式。你会想,噢!原来还可以这样。这是书本或者网站教程 所不能教给你的。而且,对一些教程&#…

【深度解析】OSPF-开放式最短路径优先协议

目录 重点: VPN---Virtual Private Network(虚拟专用网络隧道) OSPF网络类型: 表格视图: P2P---点对点协议 BMA---广播多路访问网络 NBMA---非广播多路访问网络 P2MP---点对多点协议 OSPF认证:检测类型+密码 …

陪诊师接单app开发|陪诊小程序开发|陪诊师接单系统开发

随着人们健康意识的提高和医疗服务的不断完善,陪诊服务逐渐受到人们的关注和需求。为了满足顾客的需求,陪诊小程序应运而生。下面将介绍陪诊小程序开发的几个优势。   1. 提供方便的预约和服务体验   陪诊小程序可以让顾客随时随地通过手机预约陪诊服…

Java034——反射(Reflection)

一、Java中的反射及作用 Java的反射(reflection)机制是指在程序的运行状态中: 可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。 一句话&#…

3.类与对象

Java作为一种面向对象语言。支持以下基本概念: 多态继承封装抽象类对象实例方法重载 1.类与对象 对象:对象是类的一个实例,有状态和行为 类:类是一个模板,它描述一类对象的行为和状态 public class Dog {String bree…

编程语言里的转义字符真的叫转义字符吗?

我们先来看看别人是怎么说转义字符的? 这是我随便从两本书上截图来的,总的来说就是反斜杠加几个字符就是转义字符。 就问你晕不晕,斜杠加几个字符至少是两个字符,那还叫字符吗,那叫字符串吧,怎么取名转义字…

ModaHub魔搭社区:AI原生云向量数据库Zilliz Cloud与 LlamaIndex 集成搭建文档问答系统

目录 准备工作 准备数据 主要参数 处理数据 开始提问 本文将演示如何与集成 LlamaIndex 从指定源获取信息。 在 ChatGPT 占领各大头条时,越来越多的企业在考虑如何在它们的产品中使用 ChatGPT。一个比较大的使用场景就是如何使用 ChatGPT 来改造产品文档孱弱的搜索能力。…

【板栗糖GIS】——通过插件调教网页版b站首页

【板栗糖GIS】——通过插件调教网页版b站首页 参考视频:利用adblock关掉热搜和搜索推荐_哔哩哔哩_bilibili 在edge浏览器上使用的插件为Adblockplus,可以在插件中心查询到 拦截元素如下: bilibili.com##.adblock-tipsbilibili.com##.trend…

2023/7/15总结

JWT 在写项目的时候,本来想着把用户的数据全部存入session这样的话就不用每次都需要带用客户端的账号。后面了解到JWT,这个是在服务器无状态的一个方式。 具体是分为三个部分,第一个是头部主要存储用到的算法等信息,第二个是载荷…

51单片机--DS1302时钟

文章目录 DS1302引脚定义和应用电路内部结构框图寄存器的定义时序定义BCD码DS1302时钟代码 DS1302 DS1302是美国DALLAS公司推出的一款实时时钟电路芯片。它具有高性能和低功耗的特点,可以通过SPI三线接口与CPU进行同步通信。DS1302能够提供秒、分、时、日、星期、月…

HTML基础教程

1 什么是HTML HTML 是用来描述网页的一种语言。HTML 是一种在 Web 上使用的通用标记语言。HTML 允许你格式化文本,添加图片,创建链接、输入表单、框架和表格等等,并可将之存为文本文件,浏览器即可读取和显示。 HTML 指的是超文本…

复用cmake代码的其他方法

复用cmake代码的其他方法 函数和宏是代码复用的方法,在cmake3.18版本开始,cmake添加了cmake_language()命令,通过这个命令我们可以直接调用任意的cmake代码,无需将这些可复用的代码使用函数或者宏包起来. 当然cmake_language()命令不是为了代替函数和宏而设计的,而是希望通过…

ROS话题通信自定义msg

从21年至今写过不下10个ROS话题通信的工程,今天系统地记录下自定义msg的过程,让后来者少走弯路。 1、自定义msg简介 在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:Stri…

redis7单节点、主从、哨兵、集群的安装和配置

redis7安装和配置 2022年4月份正式发布的redis 7.0,是目前历史上变化最大的版本,有超过50个以上的新增命令 官网: https://redis.io中文镜像 http://redis.cn中文学习网: https://redis.com.cn/redis版本,建议升级…