Rust 语言常见的一些概念(下)

简介: Rust 语言常见的一些概念(下)

1、函数

函数在 Rust 代码中非常普遍。你已经见过语言中最重要的函数之一:main 函数,它是很多程序的入口点。你也见过 fn 关键字,它用来声明新函数。

Rust 代码中的函数和变量名使用 snake case 规范风格,也就是蛇形命名规范,跟python语言是一样的。在 snake case 中,所有字母都是小写并使用下划线分隔单词。这是一个包含函数定义示例的程序:

一个示例如下所示:

fn hello_world() {
    println!("hello world !")
}
fn main() {
    println!("main ......");
    hello_world()
}

注意,hello_world函数定义在 main 函数 之后;也可以定义在之前。Rust 不关心函数定义所在的位置,只要函数被调用时出现在调用之处可见的作用域内就行。它是静态语言不像其他动态(JavaScript)那样,从上往下执行,那样会找不到对应的函数。

我们可以以下以上方法,看下结果,如下所示:

参数

我们可以定义为拥有 参数parameters)的函数,参数是特殊变量,是函数签名的一部分。当函数拥有参数(形参)时,可以为这些参数提供具体的值(实参)。技术上讲,这些具体值被称为参数(arguments)。

在上面hello_world函数中,我们增加了一个参数:

fn hello_world(p: i64) {
    println!("hello world {p}!")
}
fn main() {
    println!("main ......");
    hello_world(1024)
}

运行以上程序,结果如下所示:

在函数签名中,必须 声明每个参数的类型。这是 Rust 设计中一个经过慎重考虑的决定:要求在函数定义中提供对用的类型说明,意味着编译器再也不需要你在代码的其他地方注明类型来指出你的意图。而且,在知道函数需要什么类型后,编译器就能够给出更有用的错误消息。

当定义多个参数时,使用逗号分隔,像这样:

fn hello_world(c: &str,p: i64,) {
    println!("hello world {c} {p}!")
}
fn main() {
    println!("main ......");
    hello_world("程序员的", 1024)
}

运行一下代码,如下所示:

语句和表达式

函数体由一系列的语句和一个可选的结尾表达式构成。目前为止,我们提到的函数还不包含结尾表达式,不过你已经见过作为语句一部分的表达式。因为 Rust 是一门基于表达式(expression-based)的语言,这是一个需要理解的(不同于其他语言)重要区别。其他语言并没有这样的区别,所以让我们看看语句与表达式有什么区别以及这些区别是如何影响函数体的。

语句Statements)是执行一些操作但不返回值的指令。 表达式Expressions)计算并产生一个值。让我们看一些例子。

fn main() {
    let x = 12345;
    println!("========={x}========");
}

let x = 12345; 这是一个语句。而等号后面的12345则是一个表达式。

具有返回值的函数

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

下面是一个具有返回值函数的示例:

fn main() {
    let y = y();
    println!("数字是:{y}")
}
fn y() -> i32 {
   12345
}

运行以上代码,如下所示:

y函数没有参数并定义了返回值类型,不过函数体只有单单一个 12345 也没有分号,因为这是一个表达式,我们想要返回它的值。如果加上分号,就是一个语句,就会报错了。

fn main() {
    let y = y();
    println!("数字是:{y}")
}
fn y() -> i32 {
   12345;
}

运行以上代码就会报以下错误:

主要的错误信息,“mismatched types”(类型不匹配),揭示了代码的核心问题。函数 y的定义说明它要返回一个 i32 类型的值,不过语句并不会返回值,使用 () 表示不返回值。因为不返回值与函数定义相矛盾,从而出现一个错误。在输出中,Rust 提供了一条信息,可能有助于纠正这个错误:它建议删除分号,这会修复这个错误。

2、注释

所有程序员都力求使其代码易于理解,不过有时还需要提供额外的解释。在这种情况下,程序员在源码中留下 注释comments),编译器会忽略它们,不过阅读代码的人可能觉得有用。

这是一个简单的注释:

// 返回一个数字
fn y() -> i32 {
   12345
}

文档注释

Rust 也有特定的用于文档的注释类型,通常被称为 文档注释documentation comments),它们会生成 HTML 文档。这些 HTML 展示公有 API 文档注释的内容,它们意在让对库感兴趣的程序员理解如何 使用。

以下是一个示例:

/// 返回一个数字(i32)
/// 参数:p 类型i32
/// message:......
/// 这是一个返回一个数字的函数
/// 
fn y(p:i32) -> i32 {
   p
}

多行注释

跟其他语言一样也可以书写多行注释,如下所示:

/**
 * 这是一个返回整数的方法
 * params: p(i32)
 * return: i32 
 */
fn y(p:i32) -> i32 {
   p
}

3、控制流

3.1 if 表达式

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

以下是一个示例:

fn main() {
    let y = 1234;
    if y > 1024 {
        println!("满足条件!")
    } else {
        println!("不满足条件!")
    }    
}

值得注意的是代码中的条件 必须bool 值。如果条件不是 bool 值,我们将得到一个错误。例如,尝试运行以下代码:

fn main() {
    let y = 1234;
    if y {
        println!("满足条件!")
    } else {
        println!("不满足条件!")
    }    
}

这个错误表明 Rust 期望一个 bool 却得到了一个整数。Rust作为一门静态语言,不会像JavaScript语言那样会进行动态的转换。

3.2 使用esle if 处理多重条件

可以使用if 和 else if 来处理多重条件的判断,以下是一个示例:

fn main() {
    let y = 1234;
    if y > 1000 {
        println!("大于1000!")
    } else if y > 100 {
        println!("大于100!")
    } else if y > 10 {
        println!("大于10!")
    } else {
        println!("小于于10!")
    }   
}

3.3 在 let 语句中使用 if

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

fn main() {
    let y = true;
    let res = if y {0} else {1};
    println!("res: {res}")
}

if 的每个分支的可能的返回值都必须是相同类型,否则会报错,代码改变一下,如下所示:

fn main() {
    let y = true;
    let res = if y {0} else {false};
    println!("res: {res}")
}

3.4 使用循环重复执行

Rust 有三种循环:loopwhilefor

使用 loop 重复执行代码

loop 关键字告诉 Rust 一遍又一遍地执行一段代码直到你明确要求停止。

fn main() {
    loop {
        println!("res:")
    }
}

当运行这个程序时,我们会看到连续的反复打印 again!,直到我们手动停止程序。大部分终端都支持一个快捷键,ctrl-c,来终止一个陷入无限循环的程序。

从循环中返回值

通过loop循环,我们可以通过break语句来中断循环,并返回结果,举一个例子,如下所示:

fn main() {
   let mut i = 0; 
   let res = loop {
        i += 1;
        if i == 5 {
            break i * i;
        }
    };
    println!("res: {res}")
}

循环标签:在多个循环之间消除歧义

如果存在嵌套循环,breakcontinue 应用于此时最内层的循环。你可以选择在一个循环上指定一个 循环标签loop label),然后将标签与 breakcontinue 一起使用,使这些关键字应用于已标记的循环而不是最内层的循环。

以下是一个示例:

fn main() {
   let mut i = 0; 
   'first: loop {
        i += 1;
        loop {
            if i % 2 == 0 {
                i += 1;
                break 'first;
            } else {
                break; 
            }
        }
    }
    println!("res: {i}")
}

首先定义的可变变量i=0; 进入第一个循环的时候i+1,i的结果为1,进入到第二个循环判断i对2求余是否等于0,结果不等进入else语句块中,在else语句块出现break语句,跳出当前循环,进入到i += 1的位置,所有此时i等于2,然后再次进去第二个循环,i对2求余结果等于0,对i进行加1操作,此时i等于3,然后跳到标签循环的位置,然后往下执行打印结果:"res:3".

while 条件循环

在程序中计算循环的条件也很常见。当条件为 true,执行循环。当条件不再为 true,调用 break 停止循环。这个循环类型可以通过组合 loopifelsebreak 来实现;

以下是一个示例:

fn main() {
   let mut i = 0; 
   while i < 10 {
    i += 1;
    println!("res: {i}")
   }
}

使用for遍历集合

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

下面是一个使用 for 循环的例子:

fn main() {
   let numbers = [10, 20, 30, 40, 50]; 
   for i in numbers {
    println!("{i}")
   }
}

 


相关文章
|
3月前
|
Rust 安全 网络协议
Rust 笔记:Rust 语言中的枚举 与 模式匹配
Rust 笔记:Rust 语言中的枚举 与 模式匹配
47 0
|
3月前
|
存储 Rust 安全
Rust 笔记:Rust 语言中的 所有权 与 生命周期
Rust 笔记:Rust 语言中的 所有权 与 生命周期
132 0
|
1月前
|
Rust 监控 数据安全/隐私保护
Rust语言在员工屏幕监控系统中的应用指南
员工屏幕监控系统在现代企业管理中扮演着重要角色。它们能够帮助企业监控员工的活动,确保他们的工作效率和数据安全。在这篇文章中,我们将探讨如何使用Rust语言构建一个简单而高效的员工屏幕监控系统,并提供一些代码示例以帮助你入门。
111 0
|
2月前
|
Rust 监控 JavaScript
抖音技术分享:飞鸽IM桌面端基于Rust语言进行重构的技术选型和实践总结
本文将介绍飞鸽IM前端团队如何结合Rust对飞鸽客户端接待能力进行的技术提升,一步步从概念验证、路径分解到分工开发,再到最后上线收益论证,并分享了其中遇到的技术挑战与经验总结等。
58 1
|
2月前
|
Rust 安全 前端开发
Rust还是其他语言:考量因素与案例分析
【2月更文挑战第1天】本文将探讨在选择编程语言时,为什么Rust可能会成为理想的选择。我们将分析Rust的主要优势,如内存安全、性能、并发编程和所有权系统,并将其与其他流行的编程语言进行比较。此外,我们还将通过具体的案例分析,展示Rust在实际应用中的优势和应用场景。
|
2月前
|
Rust 安全 开发者
Rust中的元编程概念与应用
本文将深入探讨Rust编程语言中的元编程概念,包括宏、特性、元组和元函数等,并展示它们在Rust中的实际应用。元编程允许开发者在编译时操纵代码,实现代码生成、条件编译、类型检查等高级功能。通过本文的讲解,读者将能够更好地理解元编程在Rust中的作用,并学会如何在项目中应用元编程技术。
|
2月前
|
Rust 安全 Java
Rust 语言的类型系统
假如让你设计编程语言的类型,你会怎么做? 要定义哪些类型? 类型之间如何交互? 是否需要类型推断? 类型系统是编程语言中用于定义和控制类型的一组规则。
Rust 语言的类型系统
|
2月前
|
Rust 安全
Rust语言中的控制流:条件语句、循环与模式匹配详解
本文将深入探讨Rust编程语言中的控制流构造,包括条件语句、循环和模式匹配。我们将了解如何使用这些工具来构建高效、可读和安全的代码。此外,我们还将探讨Rust在这些构造中提供的一些独特功能和优化。
|
3月前
|
存储 缓存 Rust
Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用
Rust 笔记:Rust 语言中哈希结构(哈希映射,HashMap)、集合(哈希集,HashSet)及其使用
359 0
|
3月前
|
存储 Rust 安全
Rust 笔记:Rust 语言中的 结构体 与面向对象编程的实现
Rust 笔记:Rust 语言中的 结构体 与面向对象编程的实现
78 0