rust学习-函数的定义与使用

rust学习-函数的定义与使用

  • 1. 函数的基本定义
  • 2. 函数的参数
    • 多个参数
  • 3. 返回值
    • 提前返回
  • 4. 函数调用
  • 5. 函数的所有权和借用
    • 传递所有权
    • 借用
  • 6. 函数作为参数和返回值
    • 函数作为参数
    • 函数作为返回值
  • 7. 泛型函数
  • 8. 函数注释(文档注释)

1. 函数的基本定义

在Rust中,函数使用fn关键字来定义:

fn say_hello() {println!("Hello, world!");
}
  • fn:定义函数的关键字
  • say_hello:函数的名字
  • ():函数的参数列表,当前函数没有参数
  • {}:函数体,包含了函数执行的代码

2. 函数的参数

函数可以接受参数,参数的类型必须在函数签名中明确指定:

fn greet(name: &str) {println!("Hello, {}!", name);
}
  • name: &str:函数的参数定义,name是参数的名称,&str是参数的类型(&str表示一个字符串切片)

多个参数

函数可以有多个参数,参数之间用逗号分隔:

fn add(x: i32, y: i32) {println!("The sum of {} and {} is {}.", x, y, x + y);
}
  • x: i32, y: i32:函数有两个参数,x和y,它们的类型都是i32(32位整数)

3. 返回值

函数可以返回一个值,返回值的类型在函数签名中使用->符号指定:

fn add(x: i32, y: i32) -> i32 {x + y
}
  • -> i32:表示函数返回一个i32类型的值
  • x + y:函数的返回值,在Rust中,函数体中的最后一个表达式的值会自动作为返回值,除非使用return关键字提前返回

提前返回

可使用return关键字从函数中间返回一个值:

fn divide(x: i32, y: i32) -> Option<i32> {if y == 0 {return None; // 提前返回}Some(x / y)
}
  • Option:表示函数的返回值是一个Option类型,它可以是Some(i32)或None
  • return None;:在y == 0的情况下,函数会提前返回None

4. 函数调用

定义函数后,可以通过函数名来调用它,调用函数时,必须提供与函数签名中定义的参数相匹配的参数:

fn main() {say_hello(); // 调用无参数函数greet("XiaoMing"); // 调用带有一个参数的函数add(3, 4); // 调用带有两个参数的函数let result = add(5, 6); // 调用带有返回值的函数println!("The result is {}.", result);
}
  • say_hello():调用无参数的函数
  • greet(“XiaoMing”):调用带有一个参数的函数,传入字符串"XiaoMing"
  • add(3, 4):调用带有两个参数的函数,传入3和4
  • let result = add(5, 6):调用带有返回值的函数,并将返回值存储在变量result中

5. 函数的所有权和借用

Rust的所有权系统对函数参数的处理有一些特殊的规则,当将一个变量传递给函数时,Rust会根据参数的类型来决定是传递所有权还是借用

传递所有权

如果参数类型是T(非引用类型),则传递所有权,意味着函数内部对该参数的修改不会影响外部变量,因为外部变量的所有权已经被转移给函数了,例如:

fn take_ownership(s: String) {println!("Inside function: {}", s);
} // 这里s离开作用域,内存被释放fn main() {let my_string = String::from("Hello");take_ownership(my_string); // my_string的所有权被转移// println!("{}", my_string); // 这里会报错,因为my_string的所有权已被转移
}

借用

如果参数类型是&T(引用类型),则传递的是引用(借用),意味着函数内部对参数的修改不会影响外部变量,且函数执行完毕后,外部变量仍然拥有所有权,例如:

fn borrow(s: &String) {println!("Inside function: {}", s);
} // 这里s离开作用域,但不会释放内存,因为只是借用fn main() {let my_string = String::from("Hello");borrow(&my_string); // 传递借用println!("{}", my_string); // 这里可以正常打印my_string
}

6. 函数作为参数和返回值

Rust支持将函数作为参数传递给其他函数,也可将函数作为返回值返回,这需要使用函数指针(fn)或闭包(Fn trait)

函数作为参数

可以将函数作为参数传递给另一个函数:

fn apply(f: fn(i32) -> i32, x: i32) -> i32 {f(x)
}fn square(x: i32) -> i32 {x * x
}fn main() {let result = apply(square, 5); // 将square函数作为参数传递println!("Result: {}", result); // 输出25
}
  • apply函数接受一个函数f作为参数,并调用它
  • square函数计算一个数的平方,并返回结果

函数作为返回值

可以返回一个函数:

fn create_greeter(greeting: &str) -> impl Fn(&str) -> String {move |name| format!("{} {}!", greeting, name)
}fn main() {let greeter = create_greeter("Hello");println!("{}", greeter("XiaoMing")); // 输出 "Hello XiaoMing!"
}
  • create_greeter函数返回一个闭包(匿名函数),这个闭包接受一个字符串参数并返回一个新的字符串
  • greeter变量存储了返回的闭包,并在调用时使用

7. 泛型函数

Rust支持泛型函数,可编写可以处理多种类型的函数,泛型函数使用语法来定义泛型类型参数:

fn print_twice<T: std::fmt::Debug>(value: T) {println!("{:?}", value);println!("{:?}", value);
}fn main() {print_twice(3); // 输出3两次print_twice("Hello"); // 输出"Hello"两次
}
  • <T: std::fmt::Debug>:表示T是一个泛型类型,它必须实现了Debug trait(用于格式化输出)
  • print_twice函数可以接受任何实现了Debug trait的类型

8. 函数注释(文档注释)

Rust支持使用文档注释来为函数添加注释,这些注释可以生成文档,文档注释以///开头:

/// 这个函数接受两个整数并返回它们的和
///
/// # Examples
///
/// ```
/// let result = add(3, 4);
/// assert_eq!(result, 7);
/// ```
fn add(x: i32, y: i32) -> i32 {x + y
}
  • ///:表示这是一个文档注释
  • #Examples:用于展示示例代码
  • 这些注释可以通过cargo doc命令生成文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/67610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux 源码】内核态到用户态

文章目录 1. 由来2. 流程图3. 中断3.1 概念3.2 8259A芯片3.4 中断时的栈处理3.4.1 相同特权级3.4.2 不同特权级 3.5 中断流程3.6 定位中断程序3.7 中断流程步骤总结 4. 源码4.1 move_to_user_mode4.2 0号进程4.3 TSS和LDT在GDT表排布4.4 ldt中的0x17栈段 5. 总结 1. 由来 ​ 首…

雷电9最新版安装Magisk+LSPosd(新手速通)

大家好啊&#xff01;我是NiJiMingCheng 我的博客&#xff1a;NiJiMingCheng 在安卓系统的定制与拓展过程中&#xff0c;获取 ROOT 权限以及安装各类框架是进阶玩家常用的操作&#xff0c;这可以帮助我们实现更多系统层面的个性化功能。今天&#xff0c;我将为大家详细介绍如何…

《Linux服务与安全管理》| 邮件服务器安装和配置

《Linux服务与安全管理》| 邮件服务器安装和配置 目录 《Linux服务与安全管理》| 邮件服务器安装和配置 1.在Server01上安装dns、postfix、dovecot和telnet&#xff0c;并启动 2&#xff0e;在Server01上配置DNS服务器&#xff0c;设置MX资源记录 3&#xff0e;在server1上…

计算机毕业设计Python电商品推荐系统 商品比价系统 电商比价系统 商品可视化 商品爬虫 机器学习 深度学习 京东爬虫 国美爬虫 淘宝爬虫 大数据

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【银河麒麟高级服务器操作系统】业务访问慢网卡丢包现象分析及处理过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;product.kylinos.cn 开发者专区&#xff1a;developer.kylinos.cn 文档中心&#xff1a;document.kylinos.cn 交流论坛&#xff1a;forum.kylinos.cn 服务器环境以及配置 【内核版本…

鸿蒙开发中的骨架图:提升用户体验的关键一环

大家好&#xff0c;我是小 z&#xff0c;今天要给大家分享一个提升用户体验的超实用技巧 —— 骨架图&#x1f3af; 文章目录 一、什么是骨架图二、骨架图的作用三、鸿蒙开发中实现骨架图的方法1. 利用 opacity 奠定视觉基础2. animateTo 驱动动态变化3. 二者协同触发与展示 四…

leetcode刷题记录(七十三)——543. 二叉树的直径

&#xff08;一&#xff09;问题描述 543. 二叉树的直径 - 力扣&#xff08;LeetCode&#xff09;543. 二叉树的直径 - 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 r…

【esp32小程序】小程序篇02——连接git

一、创建仓库 进入gitee官网&#xff0c;登录&#xff08;如果没有gitee账号的就自行注册一下&#xff09;。 点击号-->新建仓库 填写好必填信息&#xff0c;然后点击“创建” 二、微信开发者工具配置 在微信开发者工具打开我们的项目。按下面的步骤依次点击 三、验证 点…

Linux的基本指令(上) -- 0基础入门

目录 知识点引入 基本指令 ls指令 pwd 命令 cd 指令 touch 指令 stat指令 mkdir 指令 tree指令 rmdir 指令 rm 命令 man 指令 which 指令 alias 指令 echo指令 输出重定向: > 追加重定向&#xff1a;>> cp 指令 知识点引入 1. Linux中路径用 / 作为路径分隔…

Java测试开发平台搭建(九)前端

1. 搭建前端vue环境 Vue3 安装 | 菜鸟教程 2. 创建项目 1.进入ui vue ui 2. create项目 3. 成功之后添加插件&#xff1a; cli-plugin-router vue-cli-plugin-vuetify 4. 添加依赖 axios 5. 点击任务开始运行 如果报错&#xff1a; 修改vue.config.jsconst { defineConfig }…

基于SpringBoot+Vue的智慧动物园管理系统的设计与实现

获取源码&#xff1a;基于SpringBootVue智慧动物园系统设计与实现: 后台和用户前台。后台包括首页、员工管理、考勤管理、部门管理、角色管理、审核管理、动物管理、演出管理、园区管理、园区设施维修、饲养管理、行为观察管理、疫苗管理、看护管理、个人中心、票务管理、收入管…

55.【5】BUUCTF WEB NCTF2019 sqli

进入靶场 输入admin 123 过滤的这么严格&#xff1f;&#xff1f;&#xff1f; 过滤很严格&#xff0c;此时要么爆破&#xff0c;要么扫描 直接扫描&#xff0c;得到robots.txt 访问后又得到hint.txt 继续访问 图片内容如下 $black_list "/limit|by|substr|mid|,|admi…

【前端】用OSS增强Hexo的搜索功能

文章目录 前言配置 _config.fluid.yml云端实时更新 local-search.xml解决 OSS.Bucket 的跨域问题 前言 原文地址&#xff1a;https://blog.dwj601.cn/FrontEnd/Hexo/hexo-enhance-local-search-with-oss/ 考虑到某著名云服务商提供的云服务器在两年的 99 计划后续费价格高达四…

Hive SQL必刷练习题:留存率问题

首次登录算作当天新增&#xff0c;第二天也登录了算作一日留存。可以理解为&#xff0c;在10月1号登陆了。在10月2号也登陆了&#xff0c;那这个人就可以算是在1号留存 今日留存率 &#xff08;今日登录且明天也登录的用户数&#xff09; / 今日登录的总用户数 * 100% 解决思…

Ubuntu 24.04 LTS 系统语言英文改中文

Ubuntu 24.04 LTS 修改软件源 Ubuntu 更改软件源 修改语言 无需输入命令&#xff0c;为Ubuntu 24.04系统添加中文智能拼音输入法 在 setting 的 system 中按下图操作 点击“Apply Changes”。需要管理员密码&#xff0c;安装完成后&#xff0c;退出登录&#xff0c;重新登…

【从零开始入门unity游戏开发之——C#篇46】C#补充知识点——命名参数和可选参数

考虑到每个人基础可能不一样&#xff0c;且并不是所有人都有同时做2D、3D开发的需求&#xff0c;所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要讲解C#的基础语法&#xff0c;包括变量、数据类型、运算符、…

大模型WebUI:Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(6)

大模型WebUI&#xff1a;Gradio全解11——Chatbot&#xff1a;融合大模型的多模态聊天机器人&#xff08;6&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.6 为LLM Agent构建UI11.6.1 使用transformers.agents11.6.2 使用Langchain agents11…

springboot基于前后端分离的摄影知识网站

Spring Boot 基于前后端分离的摄影知识网站 一、项目概述 Spring Boot 基于前后端分离的摄影知识网站&#xff0c;是一个专为摄影爱好者、专业摄影师打造的知识共享与交流平台。借助 Spring Boot 强大的后端架构搭建能力&#xff0c;结合前端独立开发的灵活性&#xff0c;整合…

VD:生成a2l文件

目录 前言Simulink合并地址 ASAP2 editor 前言 我之前的方法都是通过Simulink模型生成代码的过程中顺便就把a2l文件生成出来了&#xff0c;这时的a2l文件还没有地址&#xff0c;所以紧接着会去通过elf文件更新地址&#xff0c;一直以为这是固定的流程和方法&#xff0c;今天无…

物联网与前沿技术融合分析

【前言】 在科技发展的滚滚浪潮中&#xff0c;物联网作为连接物理世界与数字世界的桥梁&#xff0c;正日益凸显其关键作用。近年来&#xff0c;物联网与其他前沿技术的融合不断催生新的应用场景与创新模式&#xff0c;为各个领域带来了深刻变革。 物联网与人工智能的深度融合&…