首页 > 编程语言 >02.编程基本概念

02.编程基本概念

时间:2022-11-17 16:34:12浏览次数:37  
标签:02 编程 number let Rust println main 基本概念 fn

一、变量与可变性

1、变量

在Rust语言中,变量默认是不可变的(immutable)。当变量不可变时,一旦值被绑定到一个名称上,你就不能改变这个值。

fn main() {
    let mut x = 5;
    println!{"The value of x is: {x}"};
    x = 6;
    println!{"The value of x is: {x}"};
}

Rust通过mut将变量是否可变的决定权交给你,在变量前添加mut即可让变量可变。

2、常量

常量(constants)是绑定到一个名称的不允许改变的值。
常量与变量的区别:

  1. 不允许对常量使用mut,常量不光默认不能变,它总是不能改变;
  2. 声明常量使用const关键字而不是let,并且必须注明值得类型;常量可以在任何作用域中声明,在声明它的作用域之中,常量在整个程序生命周期中都有效;
  3. 常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出得值;
    声明常量的例子:
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

Rust对常量的命名约定是在单词使用全大写并在单词之间添加下划线_

3、隐藏

在Rust中我们定义一个与之前变量同名的新变量,这称之为”第一个变量被第二个变量隐藏(Shadowing)“。第二个变量”隐藏“了第一个变量,此时任何使用该变量名的行为都会被视为在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。

fn main() {
    let x = 5;

    let x = x + 1;
    
    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x} ");
    }
    println!("The value of x is: {x}");
}

输出如下:

隐藏与变量标记为mut是有区别的:

  1. 当不小心尝试对变量重新赋值时,如果没有使用let关键字,就会导致编译错误,并且隐藏不改变值得不可变状态;
  2. 当再次使用let时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。

二、数据类型

在Rust中,每一个值都属于某一种数据类型(data type)。Rust时静态类型语言,在编译时必须直到所有变量的类型。

1、标量类型

标量(scalar)类型代表一个单独的值。

1.整形

整形是一个没有小数部分的数字。该类型表明,它关联的值应该是一个占据32位bit的无符号整数(有符号整数类型以i开头,无符号整数类型u开头)。

有符号:代表这个数有可能是负数;
无符号:代表这个数永远为正数;
另外isizeusize类型依赖运行程序的计算机架构:64位架构上它们是64位,32位架构上它们是3位。
可以使用如下表格中的任何一种形式编写数字面值。

例如:1_000它的值与你指定的1000相同。

2.浮点型

Rust有两个原生的浮点数类型。它们都是带小数点的数组。它们是f32f64,分别占32位和64位。默认类型是f64。所有的浮点型都是有符号的。

3.数值运算

Rust中的所有数字类型都支持基本数学运算:加法、减法、除法和取余。整数除法会向下舍入到最接近的整数。

fn main() {
    let rets: u32 = 43 / 5;
    println!("The {rets}");
}

4.布尔型

Rust中的布尔类型有可能的值:TrueFalse。Rust中的布尔类型使用bool表示。使用布尔值的主要场景是条件表达式。

5.字符类型

Rust的char类型是语言中最原生的字母类型。注意,我们用单引号声明char字面量,而与之相反的是,使用双引号声明字符串字面量。Rust的char类型的大小位4个字节,并代表了一个Unicode标量值

2、复合类型

复合类型可以将多个值组合成一个类型。Rust有两个原生的复合类型:元组(tuple)和数组(array)。

1.元组类型

元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增长和缩小。

fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}

tup变量绑定到整个元组上,因为元组是一个单独的符合元素。为了从元组中获取单个值,可以使用模式匹配(pattern matching)来解构(destructure)元组值。

fn main() {
    let tup = (500, 6.4, 1);

    let (x, y, z) = tup;

    println!("The value of y is: {x} {y} {z}");
}

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

2.数组类型

另一个包含多个值的方式是数组(array),数组是在栈(stack)上为数据分配已知固定大小的单个内存块空间。与元组不同,数组中的每个元素的类型必须相同。Rust中的数组长度是固定的。

fn main() {
    let a = [1, 2, 3, 4, 5];
}

但是数组不如vector类型灵活,vector类型是标准库提供的一个允许增长和缩小长度的类型数组的集合类型。

三、函数/参数

1、函数

main函数是很多程序的入口点。fn关键字,它用来声明函数。

fn main() {
    println!("Hello, world!");

    another_function();
}

fn another_function() {
    println!("Another function.");
}

注意,在源代码中another_function定义在main函数之后;也可以定义在之前。Rust不关心函数定义所在的位置,只要函数被调用时出现在调用之处可见的作用域内就行。

2、参数

参数是特殊变量,是函数签名的一部分。形参(parameter)和(argument)来表示函数定义中的变量或调用函数时传入的具体值。

fn main() {
    another_function(5);
}

fn another_function(x: i32) {
    println!("The value of x is: {x}");
}

another_function的声明中有一个命名x的参数。x的类型被指定为i32,这个x则为形参;当我们将5传入another_function时,println!宏会八5放在格式字符串中包含x的那对花括号的位置,此时5为实参。
在函数签名中,必须声明每个参数的类型
当定义多个参数时,使用逗号分隔。

fn main() {
    print_labeled_measurement(5, 'h');
}

fn print_labeled_measurement(value: i32, unit_label: char) {
    println!("The measurement is: {value}{unit_label}");
}

3、语句和表达

函数体由一系列语句和一个可选的结尾表达式构成。
语句(Statements)时执行一些操作但不返回值的执行。表达式计算并产生一个值。
语句以分号结尾;表达式不以分号结尾

4、具有返回值的函数

函数可以向调用它的代码返回值。但要在箭头->)后声明它的类型。
在Rust中,函数的返回值等同于函数体最后一个表达式的值。使用return关键字和指定值,可以从函数中提前返回;但大部分函数隐式的返回最后的表达式。

fn five() -> i32 {
    5
}

fn main() {
    let x = five();

    println!("The value of x is: {x}");
}

四、注释

注释有助于理解代码。

// hello, world

五、控制流

Rust代码中最常见的用来控制执行流的结构是if表达式和循环。

1、if表达式

if表达式允许根据条件执行不通的代码分支。你提供一个条件冰雹是“如果条件满足,运行这段代码;如果条件不满足,不运行这段代码。”

fn main() {
    let number = 3;

    if number < 5 {
        println!("condition was true");
    } else {
        println!("condition was false");
    }
}

另外值得注意的是代码中的条件必须是bool

2、使用else if处理多重条件

可以使用else if表达式与ifelse组合来实现多重条件。

fn main() {
    let number = 6;

    if number % 4 == 0 {
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        println!("number is divisible by 3");
    } else if number % 2 == 0 {
        println!("number is divisible by 2");
    } else {
        println!("number is not divisible by 4, 3, or 2");
    }
}

3、在let语句使用if

因为if是一个表达式,我们可以在let语句的右侧使用它。

fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {number}");
}

在Rust中,变量必须只有一个类型。如果在变量中出现两种类型,那么就会出现错误。

fn main() {
    let condition = true;
    let number = if condition { 5 } else { "six" };

    println!("The value of number is: {number}");
}

4、使用循环重复执行

Rust使用loop重复执行代码。一个循环执行循环体中的代码直接到结尾并紧接着回到开头继续执行。

fn main() {
    loop {
        println!("again!");
    }
}

当运行这个程序时,我们会看到连续的反复打印 again!,直到我们手动停止程序。

1.从循环返回值

fn main() {
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2;
        }
    };
    println!("The result is {result}");
}

在循环之前,我们声明了一个名为 counter 的变量并初始化为 0。接着声明了一个名为 result 来存放循环的返回值。在循环的每一次迭代中,我们将 counter 变量加 1,接着检查计数是否等于 10。当相等时,使用 break 关键字返回值 counter * 2。循环之后,我们通过分号结束赋值给 result 的语句。最后打印出 result 的值,也就是 20。

2.循环标签

可以选择在玄幻上指定一个循环标签(loop label),然后将标签与breakcontinue一起使用,使这些关键字应用于已标记的循环而不是最内层的循环。

fn main() {
    let mut count = 0;
    'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;
        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                break 'counting_up;
            }
            remaining -= 1;
        }
        count += 1;
    }
    println!("End count = {count}");
}

外层循环有一个标签 counting_up,它将从 0 数到 2。没有标签的内部循环从 10 向下数到 9。第一个没有指定标签的 break 将只退出内层循环。break 'counting_up; 语句将退出外层循环。

5、While条件循环

fn main() {
    let mut number = 3;
    while number != 0 {
        println!("{number}!");
        number -= 1;
    }
    println!("LIFTOFF!!!");
}

Rust内置了一个while循环。

5、for循环

for 循环的安全性和简洁性使得它成为 Rust 中使用最多的循环结构。
使用for循环来倒计时:

fn main() {
    for number in (1..4).rev() {
        println!("{number}!");
    }
    println!("LIFTOFF!!!");
}

标签:02,编程,number,let,Rust,println,main,基本概念,fn
From: https://www.cnblogs.com/ColoFly/p/16899894.html

相关文章

  • Mac电脑专业编程和数学计算必备工具MATLAB R2022b 完美使用
     mac软件下载:MATLABR2022bforMac怎么安装Mac电脑专业编程和数学计算必备工具MATLABR2022b完美使用资源啊,商业数学软件MATLABR2022更新了,作为数学类科技应用软件......
  • 灵雀云ACP 斩获“2022金边奖-最佳云原生边缘云平台”
    近日,由边缘计算社区主办的全球边缘计算大会·上海站成功召开,灵雀云凭借出色的全栈云原生技术实力、专业的高品质服务以及在边缘云场景的丰富落地实践,斩获“2022金边奖-最佳......
  • IFR02红外雨量传感器
    IFR02是通过红外光扫描原理非接触式检测降雨量的传感器(雨量计)。n使用独特的智能学习适应算法,可在复杂光环境中使用,具有很强的抗外部干扰能力。n采用渐变脉宽调制与动态......
  • 【书籍分享】Java编程思想(Think In Java) 第四版 完整中文高清文字版 非扫描版【pdf版+
    自取:https://url03.ctfile.com/f/24333903-724740746-79fa44?p=5831(访问密码:5831),进入下载页面,选择【普通下载】压缩包内容:chm版本:pdf版本:......
  • Spring的@Async异步编程
    使用@Async注解时,推荐使用自定义线程池的模式;查看源码,@Async的默认线程池为SimpleAsyncTaskExecutor,默认线程池有如下弊端:在线程池应用中,参考阿里巴巴java开发规范:线程池不......
  • 2022NOIPA层联测29
    今天的T3的“部分分”不一定是假做法,比如我写的其它部分是正解好不容易记住了求前缀和,但是求了一个任意两点间最短路?!,而且特判了一个m<=10的小数据枚举排列打算保底结果保没......
  • [Editorial] 2022 CCPC Guangzhou Onsite
    2022CCPCGuangzhouOnsite大概按题目难度顺序排序。这篇题解可能没那么口胡。GYM104053EElevator相当于每个电梯在\(-x_i\),每次可以把最大的,编号最小的值减一,要求......
  • 视频直播app源码,react 编程式导航实现页面跳转
    视频直播app源码,react编程式导航实现页面跳转一介绍编程式导航:通过js代码来实现页面跳转 案例:点击登录按钮,登录成功后,通过代码跳转到后台首页,如何实现? 答......
  • 2022-11-17 身份证正则(转载)
    注:本文转载于https://blog.csdn.net/qq_17032077/article/details/123919813十八位:^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)......
  • 2023-李艳芳三套卷-数学三
    2023-李艳芳3(3)-1这张卷子寄了(doge)T18定义域看错了,T21漏解了,T22\(p_2\)的积分积错了,亏麻了属于是T5通过正交变换的几何意义理解(见2023-李艳芳3(1)-1)T7\(A\)对称......