首页 > 其他分享 >【Rust自学】4.3. 所有权与函数

【Rust自学】4.3. 所有权与函数

时间:2024-12-20 10:03:11浏览次数:5  
标签:函数 4.3 some String 变量 自学 所有权 Rust string

4.3.0 写在正文之前

在学习了Rust的通用编程概念后,就来到了整个Rust的重中之重——所有权,它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。

本章有三小节:

  • 所有权:栈内存 vs. 堆内存
  • 所有权规则、内存与分配
  • 所有权与函数(本文)

喜欢的话记得点赞、收藏加关注哦,想要跟着学下去记得关注专栏哦

4.3.1. 把值传递给函数

在语义上,把值传递给函数和把值赋给变量是类似的,所以一句话总结:函数参数传递跟赋值操作是一样的

接下来详细解释一下:把值传递给函数将会发生移动(Move)或者复制(Copy)

  • 对于实现了Copy trait的数据类型,会发生复制,所以原本的变量不受影响,能够继续使用
  • 对于没有实现Copy trait的数据类型,会发生复制,所以原本的变量会被弃用,不可使用

Copy trait、移动、复制的详细介绍在上一篇文章4.2. 所有权规则、内存与分配有讲,这里不再作阐述

fn main(){
	let machine = String::from("6657");
	wjq(machine);

	let x = 6657;
	wjq_copy(x);
	println!("x is:{}", x);
}

fn wjq(some_string::String){
	println!("{}", some_string);
}

fn wjq_copy(some_number::i32){
	println!("{}", some_number);
}
  • 对于变量machine

    • String 是一种复杂数据类型,分配在堆上,并且没有实现Copy trait。
    • machine 被传递给 wjq 函数时,发生了移动(Move),即所有权从变量 machine 转移到了函数参数 some_string
    • 此时,machine 的所有权被转移,函数 wjq 可以正常使用它,但原来的变量 machine 不再可用。如果尝试在之后使用 machine,编译器会报错。
  • 对于变量x

    • i32 是一种基本数据类型,大小固定,分配在栈上,并且实现了 Copy trait。
    • x 被传递给 wjq_copy 函数时,发生了复制(Copy),即变量 x 的值被复制了一份传递给了函数参数 some_number
    • 由于是值的复制,原变量 x 不受影响,可以在函数调用之后继续使用。
  • 对于变量some_string

    • 其作用域从第10行被声明开始,到第12行的}时就离开了作用域
    • 在离开作用域时Rust会自动调用drop函数释放变量some_string所占的内存
  • 对于变量some_number

    • 其作用域是从第14行被声明开始,到第16行的}时就离开了作用域
    • 离开作用域时不会有特殊的事情发生,因为实现了Copy trait的类型在离开作用域时不会调用 Drop

4.3.2. 返回值与作用域

函数在返回值的过程中同样也会发生所有权的转移。

fn main(){
	let s1 = give_ownership();
	let s2 = String::from("6657");
	let s3 = takes_and_gives_back(s2);
}

fn give_ownership() -> String {
	let some_string = String::from("machine");
	some_string
}

fn takes_and_gives_back(a_string:String) -> String {
	a_string
}
  • 函数 give_ownership 的行为:

    • give_ownership 函数创建了一个 String 类型的变量 some_string,它的所有权属于 give_ownership 函数。
    • some_string 作为返回值返回时,其所有权被转移到调用者,即变量 s1
    • 结果是,some_string 离开 give_ownership 的作用域后不会被释放,因为它的所有权已交给 s1
  • 函数 takes_and_gives_back 的行为:

    • takes_and_gives_back 函数接受一个 String 类型的参数 a_string。调用该函数时,传入的参数(s2)的所有权被转移到函数的参数 a_string
    • 函数将 a_string 返回时,其所有权从 a_string 再次转移给调用者,即变量 s3
    • 此时,变量 s2 不再可用,因为其所有权已被转移给 takes_and_gives_back,而函数的返回值赋给了 s3

一个变量的所有权总是遵循同样的模式:

  • 把一个值赋给其它变量时就会发生移动,只有实现了Copy trait 的类型(如基本类型i32, f64 等),在赋值时才会进行复制
  • 当一个包含堆数据的变量离开作用域时,它的值就会被drop函数清理掉,除非数据的所有权被移动到另一个变量上。

4.3.3. 让函数使用某个值而不获得其所有权

有的时候代码的本意是让函数使用变量,但不想因此失去对数据的使用权,这时候就可以这么写:

fn main(){
	let s1 = String::from("Hello");
	let (s2, len) = calculate_length(s1);
	println!("The length of '{}' is {}", s2, len);
}

fn calculate_length(s:String) -> (String, uszie) {
	let length = s.len();
	(s, length)
}

在这个例子中,s1不得不把所有权交给s,但这个函数在返回时把s也原封不动地返回,把数据所有权交给了s2,这样做就把数据所有权又交给了main函数里的变量,使得s1下的数据又能够在main函数中使用(虽然换了个变量名)。

这种做法太麻烦,也太笨了。 Rust针对这种场景有一个特性叫引用(Reference),让函数使用某个值而不获得其所有权。 这个特性将会在下篇文章中讲。

标签:函数,4.3,some,String,变量,自学,所有权,Rust,string
From: https://blog.csdn.net/weixin_71793197/article/details/144603048

相关文章

  • 2024 IDEA 2024.3 安装使用教程(附激活至2099年,以及常见问题处理)
    IntelliJIDEA简介IntelliJIDEA是一款非常强大的Java集成开发环境(IDE),由JetBrains公司开发。它提供了丰富的功能和工具,帮助开发者更高效地编写、调试和部署代码。下面这种方式仅供交流学习,如果有能力还请支持正版下载安装下载IDEA2024.3版本的安装包为了方便,也可以去链......
  • 【基于Windows安装配置nacos 2.4.3、开机自启动、启动默认单机模式、单机模式匹配MySQ
    【基于Windows安装配置nacos2.4.3、开机自启动、启动默认单机模式、单机模式匹配MySQL】前言一、下载安装Windows版nacos2.4.3二、配置nacos完成自启单机模式三、设置Windows开机自启四、匹配MySQL数据库总结提示:可以在官网选择下载符合自己要求的版本前言......
  • 【Rust自学】4.2. 所有权规则、内存与分配
    4.2.0写在正文之前在学习了Rust的通用编程概念后,就来到了整个Rust的重中之重——所有权,它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。本章有三小节:所有权:栈内存vs.堆内存所有权规则、内存与分配(本文)所有权与函数说......
  • 【Rust自学】4.1. 所有权:栈内存 vs. 堆内存
    4.1.0写在正文之前在学习了Rust的通用编程概念后,就来到了整个Rust的重中之重——所有权,它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。本章有三小节:所有权:栈内存vs.堆内存(本文)所有权规则、内存与分配所有权与函数喜......
  • 5年Java到AI大模型,一名程序员的转型之旅,自学成功上岸!!
    在这个科技飞速发展的时代,技术的更新换代犹如潮水般汹涌。作为一名有着5年Java开发经验的程序员,我意识到自己需要适应这种变化,寻找新的职业增长点。随着人工智能(AI)和机器学习领域的迅猛发展,以及AI大模型在各个行业应用的不断扩展,我看到了这个领域蕴藏的巨大潜力和机会。因此......
  • Geotrust OV 通配符SSL
    在数字化时代,网络安全已成为企业运营不可或缺的一部分。随着网络攻击手段的不断升级,保护网站数据传输的安全性和用户隐私变得尤为重要。SSL证书,作为确保网站安全通信的关键技术之一,扮演着至关重要的角色。在众多SSL证书中,GeoTrustOV(OrganizationValidation)通配符证书以其高效......
  • 【建议收藏】最新版IDEA2024.3及 AI Assistant 一键激活到2099
    成功永久激活一、支持的IDE和版本支持JB家族所有IDE激活支持版本为2021.3~2024.1二、如何破解激活第一步:激活工具下载为了防止破解工具被删除,通过公众号回复“「永久激活」”获取下载最新工具(如过期,请记得提醒我哦)关注公众号后台回复“「永久激活」”,获取最新激活工具和......
  • MaLoader:一款基于Tauri+Rust的免杀马生成工具
    免责声明本公众号“黑客之道HackerWay”提供的资源仅供学习,利⽤本公众号“黑客之道HackerWay”所提供的信息而造成的任何直接或者间接的后果及损失,均由使⽤者本⼈负责,本公众号“黑客之道HackerWay”及作者不为此承担任何责任,一旦造成后果请自行承担责任!简介MaLoader是一款基......
  • 【用Rust写CAD】第三章 第一个Rust程序 第二节 Rust注释
    注释用于解释代码的作用和目的,帮助开发者理解代码的行为,编译器在编译时会忽略它们。通过编写清晰和详细的文档注释,可以使代码更易于理解,并帮助其他开发者更好地利用你的代码或库。Rust提供了三种主要的注释方式:单行注释、多行注释和文档注释。‌文章目录1、单行注释2、......
  • Rust 在 Linux 下的安装
    Rust在Linux下的安装我感觉,Rust这个语言,集C,C++,Java,Scala,JavaScript,TypeScript,Python...等语言的优势于一身,极致地追求性能比肩C++,极致地追求内存安全和高并发,但学习的复杂度不及C++,个人非常看好,虽然不知道它后面的最终标签是啥,感觉啥都能做......