基本语法

变量绑定

在Rust中,变量绑定 (variable bindings) 是通过let关键字声明的:

let x = 5;
let mut x = 5;
let x: i32 = 5;
let (a, b) = (3, 4);

其中变量类型如i32一般都是可以省略的,因为Rust使用了类型推断 (type inference)。 Rust还通过模式匹配 (pattern matching) 对变量进行解构,这允许我们同时对多个变量进行赋值。

有几点是需要特别注意的:

  • 变量默认是不可改变的 (immutable),如果需要改变一个变量的值需要显式加上mut关键字。
  • 变量具有局部作用域,被限制在所属的代码块内,并且允许变量覆盖 (variable shadowing)。
  • Rust默认开启属性#[warn(unused_variable)],会对未使用的变量 (以_开头的除外) 发出警告。
  • 原生类型

    Rust内置的原生类型 (primitive types) 有以下几类:

    • 布尔类型:有两个值truefalse
    • 字符类型:表示单个Unicode字符,存储为4个字节。
    • 数值类型:分为有符号整数 (i8i16i32i64isize)、 无符号整数 (u8u16u32u64usize) 以及浮点数 (f32f64)。
    • 字符串类型:最底层的是不定长类型str,更常用的是字符串切片&str和堆分配字符串String, 其中字符串切片是静态分配的,有固定的大小,并且不可变,而堆分配字符串是可变的。
    • 数组:具有固定大小,并且元素都是同种类型,可表示为[T; N]
    • 切片:引用一个数组的部分数据并且不需要拷贝,可表示为&[T]
    • 元组:具有固定大小的有序列表,每个元素都有自己的类型,通过解构或者索引来获得每个元素的值。
    • 指针:最底层的是裸指针*const T*mut T,但解引用它们是不安全的,必须放到unsafe块里。
    • 函数:具有函数类型的变量实质上是一个函数指针。
    • 元类型:即(),其唯一的值也是()
    // boolean type
    let t = true;
    let f: bool = false;
    
    // char type
    let c = ‘c‘;
    
    // numeric types
    let x = 42;
    let y: u32 = 123_456;
    let z: f64 = 1.23e+2;
    let zero = z.min(123.4);
    let bin = 0b1111_0000;
    let oct = 0o7320_1546;
    let hex = 0xf23a_b049;
    
    // string types
    let str = "Hello, world!";
    let mut string = str.to_string();
    
    // arrays and slices
    let a = [0, 1, 2, 3, 4];
    let middle = &a[1..4];
    let mut ten_zeros: [i64; 10] = [0; 10];
    
    // tuples
    let tuple: (i32, &str) = (50, "hello");
    let (fifty, _) = tuple;
    let hello = tuple.1;
    
    // raw pointers
    let x = 5;
    let raw = &x as *const i32;
    let points_at = unsafe { *raw };
    
    // functions
    fn foo(x: i32) -> i32 { x }
    let bar: fn(i32) -> i32 = foo;

    有几点是需要特别注意的:

    • 数值类型可以使用_分隔符来增加可读性。
    • Rust还支持单字节字符b‘H‘以及单字节字符串b"Hello",仅限制于ASCII字符。 此外,还可以使用r#"..."#标记来表示原始字符串,不需要对特殊字符进行转义。
    • 使用&符号将String类型转换成&str类型很廉价, 但是使用to_string()方法将&str转换到String类型涉及到分配内存, 除非很有必要否则不要这么做。
    • 数组的长度是不可变的,动态的数组称为向量 (vector),可以使用宏vec!创建。
    • 元组可以使用==!=运算符来判断是否相同。
    • 不多于32个元素的数组和不多于12个元素的元组在值传递时是自动复制的。
    • Rust不提供原生类型之间的隐式转换,只能使用as关键字显式转换。
    • 可以使用type关键字定义某个类型的别名,并且应该采用驼峰命名法。

    结构体

    结构体 (struct) 是一种记录类型,所包含的每个域 (field) 都有一个名称。 每个结构体也都有一个名称,通常以大写字母开头,使用驼峰命名法。 元组结构体 (tuple struct) 是由元组和结构体混合构成,元组结构体有名称, 但是它的域没有。当元组结构体只有一个域时,称为新类型 (newtype)。 没有任何域的结构体,称为类单元结构体 (unit-like struct)。 结构体中的值默认是不可变的,需要使用mut使其可变。

    // structs
    struct Point {
      x: i32,
      y: i32,
    }
    let mut point = Point { x: 0, y: 0 };
    
    // tuple structs
    struct Color(u8, u8, u8);
    let android_green = Color(0xa4, 0xc6, 0x39);
    let (red, green, blue) = android_green;
    
    // A tuple struct’s constructors can be used as functions.
    struct Digit(i32);
    let v = vec![0, 1, 2];
    let d: Vec<Digit> = v.into_iter().map(Digit).collect();
    
    // newtype: a tuple struct with only one element
    struct Inches(i32);
    let length = Inches(10);
    let Inches(integer_length) = length;
    
    // unit-like structs
    struct Null;
    let empty = Null;

    一个包含..struct可以用来从其它结构体拷贝一些值或者在解构时忽略一些域:

    #[derive(Default)]
    struct Point3d {
        x: i32,
        y: i32,
        z: i32,
    }
    
    let origin = Point3d::default();
    let point = Point3d { y: 1, ..origin };
    let Point3d { x: x0, y: y0, .. } = point;

    需要注意,Rust在语言级别不支持域可变性 (field mutability),所以不能这么写:

    struct Point {
        mut x: i32,
        y: i32,
    }

    这是因为可变性是绑定的一个属性,而不是结构体自身的。可以使用Cell<T>来模拟:

    use std::cell::Cell;
    
    struct Point {
        x: i32,
        y: Cell<i32>,
    }
    
    let mut point = Point { x: 5, y: Cell::new(6) };
    
    point.y.set(7);

    此外,结构体的域默认是私有的,可以使用pub关键字将其设置成公开。

    枚举

    Rust有一个集合类型,称为枚举 (enum),对于一个指定的名称有一组可替代的值, 其中子数据结构可以存储也可以不存储数据,需要使用::语法来获得每个元素的名称。

    // enums
    enum Message {
        Quit,
        ChangeColor(i32, i32, i32),
        Move { x: i32, y: i32 },
        Write(String),
    }
    
    let x: Message = Message::Move { x: 3, y: 4 };

    与结构体一样,枚举中的元素默认不能使用关系运算符进行比较 (如==!=>=), 也不支持像+*这样的双目运算符,需要自己实现,或者使用match进行匹配。

    枚举默认也是私有的,如果使用pub使其变为公有,则它的元素也都是默认公有的。 这一点是与结构体不同的:即使结构体是公有的,它的域仍然是默认私有的。 此外,枚举和结构体也可以是递归的 (recursive)。

    函数

    要声明一个函数,需要使用关键字fn,后面跟上函数名,比如

    fn add_one(x: i32) -> i32 {
        x + 1
    }

    其中函数参数的类型不能省略,可以有多个参数,但是最多只能返回一个值, 提前返回使用return关键字。Rust编译器会对未使用的函数提出警告, 可以使用属性#[allow(dead_code)]禁用无效代码检查。

    Rust有一个特殊语法适用于分叉函数 (diverging function),它不返回值:

    fn diverges() -> ! {
        panic!("This function never returns!");
    }

    其中panic!是一个宏,使当前执行线程崩溃并打印给定信息。返回类型!可用作任何类型:

    注释

    Rust有三种注释:

    • 行注释 (line comments):以//开头,仅能注释一行。
    • 块注释 (block comments):以/*开头,以*/结尾,能注释多行,但是不建议使用。
    • 文档注释 (doc comments):以///或者//!开头,支持Markdown标记语言, 其中///等价于写属性#[doc = "..."]//!等价于#![doc = "/// ..."], 配合rustdoc可自动生成说明文档。
    let x: i32 = diverges();
    let y: String = diverges();
    // explicit conversion
    let decimal = 65.4321_f32;
    let integer = decimal as u8;
    let character = integer as char;
    
    // type aliases
    type NanoSecond = u64;
    type Point = (u8, u8);
  • Rust允许先声明变量然后再初始化,但是使用未被初始化的变量会产生一个编译时错误。
时间: 2024-10-28 20:44:51

基本语法的相关文章

&lt;javascript入门&gt;基本语法

<javascript入门>基本语法一.什么是javascript?javascript语言有什么特点?脚本语言的特点?    1.如果说css是给html页面进行化妆装饰以使html页面更加美观漂亮,那么javascript就是对html中DOM树上的节点进行增删改以使html页面实现动态的效果.    2.javascript语言是一种基于面向对象的.弱类型的.平台无关性的.安全性的语言.之所以说javascript基于面向对象是说它不是一种纯粹的面向对象,而是需要面向对象时即面向对象,需

JavaScript入门学习之一——初级语法

JavaScript是前端编辑的一种编程语言(不同于html,html是一种标记语言),所以和其他的编程语言一样,我们将会从下面几点学习 基础语法 数据类型 函数 面向对象 JavaScript的组成 实际上一个完整的JavaScript是由下面三个不同的部分组成的 核心(ECMAScript) 文档对象模型(DOM),Document object model,整合了JS,CSS及Html 浏览器对象模型(BOM),Broswer object model,整合了JS和浏览器 简单的说,ESM

javascript的基本语法、数据结构

本篇学习资料主要讲解javascript的基本语法.数据结构      无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些基本元素构成了变成基础. 一.javascript的基本语法 1.执行顺序: javascript程序按照在html文件中出现的顺序逐行执行.如果需要在整个html文件中执行,最好将其放在<head>......</head>标记中. 2.区分大小写: Javascript对字母大小写敏感,

JavaScript入门学习书籍的阶段选择

对于许多想学习 JavaScript 的朋友来说,无疑如何选择入门的书籍是他们最头疼的问题,或许也是他们一直畏惧,甚至放弃学习 JavaScript 的理由.在 JavaScript 方面,自己不是什么专家,也不是什么高手,但自己一路走来,JavaScript 从迷茫到认识,对于JavaScript 书籍的认识或许还有些借鉴价值.入门推荐首选书籍:<JavaScript DOM 编程艺术>当初读了不下 4 遍,书内容简单,易学,上手快,编程思想严谨.好的入门书,对你未来的编程都会有着深远的影响

(2)javascript的基本语法、数据结构

本篇学习资料主要讲解javascript的基本语法.数据结构      无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些基本元素构成了变成基础. 一.javascript的基本语法 1.执行顺序: javascript程序按照在html文件中出现的顺序逐行执行.如果需要在整个html文件中执行,最好将其放在<head>......</head>标记中. 2.区分大小写: Javascript对字母大小写敏感,

JavaScript入门--慕课网学习笔记

 JAVASCRIPT-(慕课网)入门篇 我们来看看如何写入JS代码?你只需一步操作,使用<script>标签在HTML网页中插入JavaScript代码.注意, <script>标签要成对出现,并把JavaScript代码写在<script></script>之间. <script type="text/javascript">表示在<script></script>之间的是文本类型(text),ja

02.JavaScript入门基础

一.JavaScript数据结构: 标识符(变量名和函数名) JavaScript语言中标识符最重要的3点就是: (1)第一个字符必须是字母.下划线(_)或美元符号这3种其中之一,其后的字符可以是字母.数字或下划线.美元符号: (2)变量名不能包含空格.加号.减号等符号: (3)标识符不能和JavaScript中用于其他目的的关键字同名: .关键字(JavaScript关键字是指在JavaScript语言中有特定含义,成为JavaScript语法中一部分的那些字) .常量(常量的指从定义开始就是

JavaScript入门基础

JavaScript基本语法 1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运算符(+,-,*,/,++,--,%).比较运算符(>,<,<=,>=,==,===,!=,!==).逻辑运算符(||,&&,!).条件运算(?:).位移运算符(|,&,<<,>>,~,^)和字符串运算符(+). 可能很多人不知道&quo

javascript入门视频第一天 小案例制作 零基础开始学习javascript

JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此,小强老师给大家写了这篇入门的javascript文章.从零基础开始学习js,使大家入门更简单,希望大家喜欢.JavaScript是一种脚本语言. 也是我们web网络中最为流行一种脚本语言.脚本语言:     1.不是独立存在的.需要依附.js就是依附在浏览器中.     2.脚本语言也是语言,也有

javascript入门进阶(一)

javascript 入门进阶 这里主要讲解一下在入门阶段很难注意的一些知识点,不一定有用.但是会了总比不会强. 1.HTML为<script>标签准备的6个属性: -async:可选.表示应该立刻下载脚本,但不应妨碍页面中的其他操作.(其他的下载可以等待) -charset:可选.表示通过src指定的代码的字符集. -defer:可选.表示脚本可以延迟到文档被解析和显示之后在执行.该版本值对外部JavaScript有效果 -src:可选.执行代码的外部文件. --type:可选.编写代码使用