热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

oracle必须声明标识符_Rust中的变量的声明和定义

变量的定义和声明Rust中合法的标识符(包括变量名、函数名、triat名等)必须由数字、字母、下划线组成,而且不能以数字开头。这个和很多语
97cdc506a42b608448e28587f5860d9c.png

变量的定义和声明

Rust中合法的标识符(包括变量名、函数名、triat名等)必须由数字、字母、下划线组成,而且不能以数字开头。这个和很多语言都是一样的。Rust将来也会允许其他Unicode字符作为标识符,还有raw identifier功能,这样可以使关键字作为标识符,比如r#self,这个用途在FFI中最多。

变量的声明: let variable : i32 = 100; , 在rust中采用的变量的声明方式不同于以往语言的声明方式,这里先看变量的声明, 变量的声明时,是变量的名字先在前,而变量的类型在后面,let variable: i32;就是这个样子。

这样变量声明的好处是,对于语法分析来说分析更为方便,并且在变量声明语句中最为重要的是变量的名字,将变量名提前突出显式变量名的重要性,对于类型是变量名的附加说明,可以通过上下文推导出变量的类型,当让rust的自动类型推导具有局限性,对于不能推导出来的类型,需要手动添加类型说明。

变量声明中的let的使用也是借鉴了函数式语言的思想,let表明的是绑定的含义,表示的是将变量名和内存作了一层绑定关系。在Rust中,一般把声明的局部变量并初始化的语句称为”变量绑定“, 这里强调的是”绑定“的含义,这里和C++/C中的”赋值初始化语句有所不同。

变量定义的一些问题

Rust中,每个变量必须被合理初始化之后才能被使用,使用未初始化变量这样的错误,在rust中是不可能出现的。

检查是否声明初始化变量

刚刚上面的let variable : i32;这个是声明,而没有给变量赋值,这个在别的语言中可能是行的通的,但是在rust中,编译器直接报错(如果在后面使用这个为赋值(定义)的变量, Rust编译器会对代码作基本的静态分支流程分析,确保变量在使用之前一定被初始化,variable没有绑定任何值,这样的代码会引起很多内存不安全的问题,比如计算结果非预期、程序崩溃,所以Rust编译器必须报错。

let variable: i32;
println!("variable = {}", variable); // error[E0381]: use of possibly unintialized 'variable'

检测分支流程是否产生为初始化变量

Rust编译器的静态分支流程分析比较严格。

fn main() {let x: i32;if true {x = 1;} else {x = 2;}println!("x = {}", x);
}

这里的if分支的所有情况都给变量x绑定了值,所以它可以运行。但是如果去掉else分支,编译器就会报错:

error: use of possibly unintialized variable : 'x'
println!("x = {}", x);

从这里可以看到编译器已经检查出来变量x没有被正确的初始化。去掉else分支后,编译器的静态分支流程分析判断出在if表达式之外的println!也用到了变量x,但并未有绑定任何值得行为。编译器的静态分支流程分析并不能识别if表达式中的条件是true, 所以他要检查所有分支的情况。(这个在程序设计语言领域中有专门去做研究的,比如软件的静态分析,一些参考材料:南京大学的软件分析课程)

要是在把println!语句也去掉的话,则可以正常编译运行,这是因为if表达式之外再也没有任何地方使用变量x, 在唯一使用到x的if表达式中已经绑定了值,所以编译正常。

// 有一个例子
fn test(condition: bool ){let x: i32; //声明xif condition {x = 1; //初始化x,这里是初始化println!("{}", x); }// 如果条件不满足,x没有被初始化//但是没有关系,只要这里不使用x就没有事
}

检测循环中是否产生未初始化变量

当循环中使用break关键字的时候,break会将分支中的变量值返回。

fn main() {let x : i32;loop {if true {x = 2;break;}}println!("{}", x);// 2
}

Rust编译器的静态分支流程分析知道,break会将x的值返回,这样loop循环之外println!可以正常打印x的值

空数组或向量可以初始化变量

当变量绑定空的数组或向量时,需要显式制定类型,否则编译器无法推断其类型。

fn main() {let a: Vec = vec![];let b: [i32; 0] = [];
}

要是不加显式类型标注的话,编译器就会报错: error[e0282]: type annotation needed 空数组或向量可以用来初始化变量,但目前暂时无法用于初始化常量或静态变量。

转移了所有权产生了未初始化变量

当将一个已经初始化的变量y绑定给另外一个变量y2时,Rust会把y看做逻辑上的未初始化变量。 这里的y和y2都是移动语义的变量,移动语义的变量会发生所有权的交接,而值语义,就像其他C++语言默认的都是传值。

fn main() {let x = 42; //原生类型都是值语义,默认存储在栈上,let y = Box::new(4); //变量是由Box装箱到堆上的, Box::new方法在堆上分配内存返回指针//并与y绑定,而指针y存储在栈上,println!("{}", y);let x2 = x;let y2 = y;//println!("{}", y);//发生了所有权的转移,所以这里的变量y可以看做没有未被初始化的变量//但是如果重新给变量绑定上一个值,变量y依然是可用的,这个过程叫做重新初始化
}




推荐阅读
  • 【技术分享】一个 ELF 蠕虫分析
    【技术分享】一个 ELF 蠕虫分析 ... [详细]
  • 本文介绍了使用Rust语言编写、保存和编译程序的简单步骤。首先,打开记事本文件并编写程序代码,然后将代码保存到一个以.rs为扩展名的文件中。接下来,使用rustc命令来编译运行程序。最后,通过命令行运行编译后的程序,得到输出结果。如果遇到编译错误,可以下载Build Tools for Visual Studio 2017来解决。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Ubuntu 用户安装 Linux Kernel 3.15 RC1
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
author-avatar
cfn7831325
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有