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

 


相关文章
|
2月前
|
Rust 安全 Go
揭秘Rust语言:为何它能让你在编程江湖中,既安全驰骋又高效超车,颠覆你的编程世界观!
【8月更文挑战第31天】Rust 是一门新兴的系统级编程语言,以其卓越的安全性、高性能和强大的并发能力著称。它通过独特的所有权和借用检查机制解决了内存安全问题,使开发者既能享受 C/C++ 的性能,又能避免常见的内存错误。Rust 支持零成本抽象,确保高级抽象不牺牲性能,同时提供模块化和并发编程支持,适用于系统应用、嵌入式设备及网络服务等多种场景。从简单的 “Hello World” 程序到复杂的系统开发,Rust 正逐渐成为现代软件开发的热门选择。
45 1
|
2月前
|
Rust 安全 程序员
Rust 语言的防错机制太惊人了!安全编码从此不再是难题,快来一探究竟!
【8月更文挑战第31天】《安全编码原则:Rust 语言中的防错机制》探讨了代码安全的重要性,并详细介绍了Rust语言如何通过内存安全模型、所有权与借用规则等特性,在编译阶段检测并阻止潜在错误,如缓冲区溢出和悬空指针。文章还讨论了类型安全、边界检查等其他安全特性,并提出了遵循不可变引用、避免裸指针及充分测试等实用编码原则,以进一步提升代码质量和安全性。随着Rust在软件开发中的应用日益广泛,掌握其安全编码原则变得尤为重要。
40 0
|
2月前
|
Rust 安全 调度
从零构建梦想操作系统:用Rust语言亲手打造专属内核,你也可以成为系统开发者!
【8月更文挑战第31天】开发操作系统内核虽具挑战,却也充满乐趣。本文将指导你从零开始,使用Rust语言构建一个简单的操作系统内核。首先安装Rust环境和交叉编译工具链,然后创建新项目`my_kernel`。通过修改`Cargo.toml`和编写启动函数,结合串口输出和`multiboot2`库,最终使用QEMU运行内核。此教程旨在帮助你理解Rust在系统开发中的应用,激发深入探索的兴趣。
45 1
|
2月前
|
Rust 安全 算法
揭秘Rust语言如何重塑区块链安全:打造坚不可摧的分布式账本新篇章!
【8月更文挑战第31天】自比特币诞生以来,区块链技术凭借其去中心化和不可篡改的特点备受关注。为了应对安全性挑战,Rust 语言凭借其内存安全特性逐渐成为区块链开发的优选。本文探讨了 Rust 如何助力区块链实现更安全的分布式账本。通过示例展示了 Rust 在避免内存泄漏、空指针引用及数据竞争等方面的优势,预示着 Rust 在高性能、高安全性需求的区块链应用中拥有广阔前景。
51 1
|
1月前
|
Rust Linux Go
Rust/Go语言学习
Rust/Go语言学习
|
2月前
|
开发者 vr&ar 机器学习/深度学习
Xamarin 开发者的未来趋势展望:掌握跨平台开发新机遇,引领移动应用创新潮流与技术变革方向
【8月更文挑战第31天】Xamarin 作为领先的跨平台开发框架,通过 C# 和 .NET 框架实现一次编写、多平台运行,简化了 iOS、Android 和 Windows 应用的开发流程。未来几年,Xamarin 开发者将面临跨平台开发普及、云集成、机器学习、AR/VR、性能优化及安全性等关键趋势。通过学习新技术并积极采用新工具,开发者能够提升应用质量和用户体验,如利用 Azure AD B2C 实现身份认证,从而在竞争激烈的市场中脱颖而出。
50 0
|
2月前
|
Rust 安全 开发者
惊爆!Xamarin 携手机器学习,开启智能应用新纪元,个性化体验与跨平台优势完美融合大揭秘!
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的巨大潜力。
34 0
|
2月前
|
开发者 API 开发框架
Xamarin 在教育应用开发中的应用:从课程笔记到互动测验,全面解析使用Xamarin.Forms构建多功能教育平台的技术细节与实战示例
【8月更文挑战第31天】Xamarin 作为一款强大的跨平台移动开发框架,在教育应用开发中展现了巨大潜力。它允许开发者使用单一的 C# 代码库构建 iOS、Android 和 Windows 应用,确保不同设备上的一致体验。Xamarin 提供广泛的 API 支持,便于访问摄像头、GPS 等原生功能。本文通过一个简单的教育应用示例——课程笔记和测验功能,展示了 Xamarin 在实际开发中的应用过程。从定义用户界面到实现保存笔记和检查答案的逻辑,Xamarin 展现了其在教育应用开发中的高效性和灵活性。
32 0
|
2月前
|
Rust 安全 Java
Rust语言在Web后端的应用:基于Actix-web构建高性能、安全可靠的服务器实践
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的无限潜力。
60 0
|
2月前
|
Rust 安全 程序员
揭秘Rust语言的内存安全秘籍:如何构建坚不可摧的系统级应用?
【8月更文挑战第31天】Rust语言凭借其独特内存安全机制在编程领域脱颖而出,通过所有权、借用与生命周期等概念,在保证高性能的同时避免了缓冲区溢出等常见错误。本文深入探讨Rust的内存安全机制,并通过示例代码展示如何利用这些机制构建高效且可靠的系统。尽管这些机制增加了学习难度,但为软件开发奠定了坚实基础,使Rust成为系统、嵌入式及网络编程的理想选择。随着社区的发展,Rust将在未来软件开发中扮演更重要角色。
38 0
下一篇
无影云桌面