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}")
   }
}

 


相关文章
|
19天前
|
Rust 安全 Java
探索Rust语言的并发编程模型
探索Rust语言的并发编程模型
|
26天前
|
Rust 安全 区块链
探索Rust语言:系统编程的新选择
【10月更文挑战第27天】Rust语言以其安全性、性能和并发性在系统编程领域受到广泛关注。本文介绍了Rust的核心特性,如内存安全、高性能和强大的并发模型,以及开发技巧和实用工具,展示了Rust如何改变系统编程的面貌,并展望了其在WebAssembly、区块链和嵌入式系统等领域的未来应用。
|
27天前
|
Rust 安全 Java
编程语言新宠:Rust语言的特性、优势与实战入门
【10月更文挑战第27天】Rust语言以其独特的特性和优势在编程领域迅速崛起。本文介绍Rust的核心特性,如所有权系统和强大的并发处理能力,以及其性能和安全性优势。通过实战示例,如“Hello, World!”和线程编程,帮助读者快速入门Rust。
51 1
|
28天前
|
Rust 安全 编译器
编程语言新宠:Rust语言的特性、优势与实战入门
【10月更文挑战第26天】Rust语言诞生于2006年,由Mozilla公司的Graydon Hoare发起。作为一门系统编程语言,Rust专注于安全和高性能。通过所有权系统和生命周期管理,Rust在编译期就能消除内存泄漏等问题,适用于操作系统、嵌入式系统等高可靠性场景。
43 2
|
13天前
|
Rust 安全
深入理解Rust语言的所有权系统
深入理解Rust语言的所有权系统
26 0
|
19天前
|
Rust 安全 前端开发
探索Rust语言的异步编程模型
探索Rust语言的异步编程模型
|
29天前
|
Rust 安全 云计算
Rust语言入门:安全性与并发性的完美结合
【10月更文挑战第25天】Rust 是一种系统级编程语言,以其独特的安全性和并发性保障而著称。它提供了与 C 和 C++ 相当的性能,同时确保内存安全,避免了常见的安全问题。Rust 的所有权系统通过编译时检查保证内存安全,其零成本抽象设计使得抽象不会带来额外的性能开销。Rust 还提供了强大的并发编程工具,如线程、消息传递和原子操作,确保了数据竞争的编译时检测。这些特性使 Rust 成为编写高效、安全并发代码的理想选择。
18 0
|
2月前
|
Rust 安全 网络安全
在 Rust 语言中,寻找企业上网行为管理软件的突破
在数字化企业环境中,上网行为管理软件对于保障网络安全和提升工作效率至关重要。Rust 语言凭借其安全性、高性能和并发性,为开发此类软件提供了新机遇。本文通过几个 Rust 代码示例,展示了如何实现网址检查、访问频率统计及访问控制等功能,旨在探索 Rust 在企业上网行为管理中的应用潜力。
36 0
|
3月前
|
Rust Linux Go
Rust/Go语言学习
Rust/Go语言学习
|
4月前
|
开发者 vr&ar 机器学习/深度学习
Xamarin 开发者的未来趋势展望:掌握跨平台开发新机遇,引领移动应用创新潮流与技术变革方向
【8月更文挑战第31天】Xamarin 作为领先的跨平台开发框架,通过 C# 和 .NET 框架实现一次编写、多平台运行,简化了 iOS、Android 和 Windows 应用的开发流程。未来几年,Xamarin 开发者将面临跨平台开发普及、云集成、机器学习、AR/VR、性能优化及安全性等关键趋势。通过学习新技术并积极采用新工具,开发者能够提升应用质量和用户体验,如利用 Azure AD B2C 实现身份认证,从而在竞争激烈的市场中脱颖而出。
61 0