Rust基础语法1

    所有权转移,Rust中没有垃圾收集器,使用所有权规则确保内存安全,所有权规则如下:

    1、每个值在Rust中都有一个被称为其所有者(owner)的变量,值在任何时候只能有一个所有者。

    2、当所有者离开作用域,这个值将被丢弃。

    3、所有权的转移时零成本的,这里不需要对新的变量开辟一块内存用于存储数据。新变量只是重新分配了资源的所有权。

    例子1:所有权传递(变量)

    fn main(){let x="hello".to_string();//"hello"的所有者为xlet y=x;//"hello"的所有者变为y,这个时候原来的所有者x已失效println!("{}",x);//}

例子2:所有权传递(函数)

    fn create_string() ->String {// 创建并返回一个新的StringString::from("Hell,ownership!")}fn transfer_ownership(s:String) -> String {//返回输入的String,转移所有权s}fn main() {//create_string函数创建了一个值"Hell,ownership!",并将所有权传递给了my_string。let my_string=create_string(); //my_string将值"Hell,ownership!"的所有权传递给了函数transfer_ownership,函数又将所有权传递给了transferred_stringlet transferred_string=transfer_ownership(my_string);//此时my_string已不再对值"Hell,ownership!"拥有所有权。println!("my_string string: {}", my_string); // 此时transferred_string对值"Hell,ownership!"拥有所有权。println!("Transferred string: {}", transferred_string); }

    克隆:

    1、当克隆一个变量时,相当于创建了数据的一个完整副本。

    2、与所有权转移相比,克隆的成本较大,因为涉及到了要内存的使用和数据的复制。

    3、所有权转移后原始变量失效,克隆之后原始变量仍然有效,并且原始变量保留了数据的所有权。这里需要注意,克隆后,两个变量是完全独立的数据实例。

    例子3:

    fn main(){let x="Hello".to_string();//x获取了"Hello"的所有权let y=x.clone();//传递x的副本给yclone_ownership(y);//传递x的副本y给函数clone_ownership//x依然对"Hello"拥有所有权println!("x String:{}",x);//y对"Hello"还拥有所有权吗?不再拥有所有权了,因为已经将所有权传递给了函数clone_ownership// println!("y String:{}",y);}fn clone_ownership(s:String){println!("{}",s);}

    引用:

    1、引用有可变引用(&mut T)和不可变引用(&T)。

    2、可变引用允许修改引用所指向的值,而不可变引用不允许修改引用所指向的值。

    3、为了防止数据竞争,Rust中在任何时间,只能拥有一个可变引用到特定的数据。

    4、由于不可变引用不会改变数据,Rust中可以拥有任意数量的不可变引用。

     例子4:

// 定义一个函数,它接受一个整数的不可变引用
fn print_int(value:&i32)
{// 打印出传入整数的值println!("The value is: {}",value);
}fn  main()
{let _int=11;// 调用函数,传入整数的不可变引用print_int(&_int); 
}

    例子5:

// 定义一个函数,它接受一个整数的可变引用
fn print_int(value:&mut i32)
{// 将整数的值加倍*value *=10; 
}fn  main()
{let mut _int=10;// 调用函数,传入整数的可变引用print_int(&mut _int);// 打印加倍后的整数值println!("The value is :{}",_int);   
}

5、生命周期参数,它可以告诉编辑器,参数的引用和返回值的引用都具有相同的生命周期。例子6中的'a就是生命周期参数

 

    例子6fn return_reference<'a>(data:&'a String)->&'a String{data //返回的引用与输入的引用具有相同的生命周期}fn main(){let external_string=String::from("Hello world");let string_ref=return_reference(&external_string);println!("{}",string_ref);// 这是安全的,因为external_string的生命周期贯穿了整个main函数}
    例子7//定义一个包含引用的结构体,需要生命周期注解struct  Item<'a>{//'a表示引用的生命周期name:&'a str,}// 实现结构体,战术如何使用生命周期impl<'a> Item<'a>{// 创建一个新的Item实例,返回一个带有生命周期的实例fn new(name:&'a str)->Self{Item {name}}}fn main(){let name =String::from("Rust Programming");// 创建一个String类型的变量let item= Item::new(&name);//借用name的引用来创建Item实例println!("Item name:{}",item.name);//打印Item中的name字段}//name的生命周期结束,item.name的引用也不再有效
    例子8fn print_shorter(r:&str){println!("The string is:{}",r);}fn main(){let long_lived_string=String::from("This is a long-lived string.");{let short_lived_str:&str=&long_lived_string;//创建一个常生命周期的引用// 下面的函数调用中,short_lived_str的生命周期会被强制缩短以匹配print_shorterprint_shorter(short_lived_str);}//short_lived_str的生命周期结束//这里long_lived_string仍然有效,因此上面的强制转换是安全的println!("{}",long_lived_string);}
    例子9fn main(){let mut data=vec![1,2,3,4,5];//创建一个不可变引用let data_ref=&data;//打印使用不可变引用的数据println!("Values via immutable reference:{:?}",data_ref);// 下面尝试创建一个可变引用将会失败,因为`data`已经被不可变引用借用let data_mut_ref = &mut data; println!("{}", data_mut_ref);// 这行会导致编译错误,编译错误如下图//下面尝试创建一个可变引用将不会失败// let data_mut_ref=&mut data;// println!("{:?}",data_mut_ref);//只有当不可变引用不再使用后,才能创建可变引用//这里不再使用不可变引用data_ref,因此可以创建可变引用// let data_mut_ref=&mut data;// data_mut_ref.push(6);// println!("Values after mutation:{:?}",data_mut_ref);}

从错误截图上看,只有使用{:?}编译器错误就不存在了。

    例子10:如果有一个或多个不可变引用&T,那么在同一作用域内不能有可变引用&mut T。
如果有一个可变引用&mut T,那么在同一作用域内不能有其他的可变引用或不可变引用&T。
编译器报错提示如下struct MyStruct{value:i32,}//这个函数尝试同时接受一个对象的可变和不可变引用fn example_fn(mutable_ref:&mut MyStruct,immutable_ref:&MyStruct){println!("Mutable reference value:{}",mutable_ref.value);println!("Immutable reference value:{}",immutable_ref);}fn  main() {let mut my_object=MyStruct{value:10};//尝试同时借用可变引用和不可变引用example_fn(&mut my_object, &my_object);}

 

 

    例子11:fn main(){let x=10;//定义一个整数变量xlet y=&x;//创建一个指向x的引用yprintln!("The value of x is:{}",x);//直接打印变量x的值。println!("The address of x is:{:p}",y);//打印引用y的地址,使用{:p}格式化指针地址println!("The value of y is:{}",y);//打印应用y的值,这里会打印出地址  注意这里打印出来的是10而不是地址,不确定是不是Rust版本的问题。println!("The value pointed to by is :{}",*y);//使用解引用操作符来打印y指向的值}
    例子12// 定义一个包含字符串引用的结构体Bookstruct Book<'a>{//'a是一个生命周期注解,表示title的生命周期title:&'a str,}fn main(){let title=String::from("The Rust Programming Language");let book=Book{//title 是一个字符串切片,他引用了title变量的数据title:&title,};println!("Book title:{}",book.title);}
    例子13// longset 函数定义了一个生命周期参数'a,这个生命周期参数制定了输入参数和返回值的生命周期必须相同。fn longset<'a>(x:&'a str,y:&'a str)->&'a str{if x.len()>y.len(){x// 如果x的长度大于y,返回x}else {y //否则,返回y}}fn main(){let string1=String::from("Rust");let string2=String::from("C++");let result=longset(string1.as_str(), string2.as_str());//longset函数比较两个字符串切片的长度println!("The longeset string is {}",result);//注意 result 的生命周期与string1和string2的生命周期相关,因此它们必须在result被使用之前保持有效}
    例子14// 定义一个结构体ImportantExcerpt,它包含一个字符串切片字段partstruct  ImportantExcerpt<'a>{part:&'a str,}fn main(){let novel=String::from("Call me ishmael. Some years ago ...");let first_sentence=novel.split('.').next().expect("Could not find a '.'");let excerpt=ImportantExcerpt{part:first_sentence,};//打印出结构体中的字符串切片println!("Important excerpt:{}",excerpt.part);}
    例子15// 定义一个结构体ImportantExcerpt,它包含一个字符串切片字段partstruct  ImportantExcerpt<'a>    {part:&'a str,}//为ImportantExcept结构体实现方法impl <'a> ImportantExcerpt<'a> {fn announce_and_return_part(&self,announcement:&str)->&str{println!("Attention please:{}",announcement);self.part}}fn main(){let novel=String::from("Call me ishmael. Some years ago ...");let first_sentence=novel.split('.').next().expect("Could not find a '.'");let excerpt=ImportantExcerpt{part:first_sentence,};let announcement="I'm going to tell you something important!";let part=excerpt.announce_and_return_part(announcement);//打印出结构体中的字符串切片println!("Important excerpt:{}",part);  }
    例子16//定义一个拥有静态生命周期的字符串常量static MESSAGE:&'static str="Hello,this is a static lifetime example";fn main(){//打印这个静态生命周期的字符串println!("{}",MESSAGE);}
    例子17//定义一个函数,该函数接收两个引用参数:一个是不带生命周期的引用,另一个是带生命周期的'a的引用fn select<'a>(first:&i32,second:&'a i32)->&'a i32{//这里我们简单地返回第二个参数,它带有生命周期'asecond}fn main(){let num1=10;let num2=20;//创建一个生命周期较长的引用let result;{let num3=num2;//调用函数,num1的引用不带生命周期,num3的引用带有生命周期result=select(&num1, &num3);}//num3的生命周期结束//打印结果,result引用的是num2,因为它与num3共享相同的数据println!("The selected number is {}",result);}
    例子18//定义一个结构体Book,包含一个字符串切片引用,代码书名struct Book<'a>{name:&'a str,}//实现Book结构体的一个方法get_name,返回书名的引用//这里没有显示标注生命周期,因为编译器会自动应用生命周期省略规则impl<'a> Book<'a>{//根据省略规则,这里的返回值生命周期被自动推导问为与&self相同fn get_name(&self)->&str{self.name}    }fn main(){let book=Book{name:"The Rust Programming Language"};//调用get_name方法,打印返回的书名引用println!("Book name:{}",book.get_name());}
例子19
// 定义一个泛型函数`slice_first`,它有一个泛型类型`T`和生命周期`'a`
fn slice_first<'a, T>(data: &'a [T]) -> Option<&'a T> {// 使用`.get()`方法来尝试获取slice的第一个元素的引用// 如果存在,则返回Some(&T),否则返回Nonedata.get(0)
}fn main() {// 创建一个整数类型的slicelet numbers = vec![1, 2, 3, 4, 5];// 调用`slice_first`函数,并打印返回的结果if let Some(first) = slice_first(&numbers) {println!("The first number is {}", first);} else {println!("The slice is empty.");}// 创建一个字符类型的slicelet letters = vec!['a', 'b', 'c', 'd', 'e'];// 同样调用`slice_first`函数,并打印返回的结果if let Some(first) = slice_first(&letters) {println!("The first letter is {}", first);} else {println!("The slice is empty.");}
}

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

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

相关文章

WordPress微信一键关注免认证登录插件

插件介绍 WordPress微信免认证快捷登录插件&#xff1a;订阅号也能一键通行 这款WordPress插件专为个人用户打造&#xff0c;无需繁琐的服务号申请与认证流程。即使您只有未认证的订阅号&#xff0c;也能轻松实现关注公众号后一键登录网站的功能&#xff01; 配置步骤简单明…

【接上篇】二、Flask学习之CSS(下篇)

上篇&#xff1a;二、Flask学习之CSS 3.8hover hover是用来美化鼠标悬停的效果的&#xff0c;当鼠标停放在某个区域&#xff0c;就会执行对应的hover操作。可以操作本标签的内容&#xff0c;也可以操作本标签下某一个标签的内容 3.9after <!DOCTYPE html> <html l…

Unity3d C#实现场景编辑/运行模式下3D模型XYZ轴混合一键排序功能(含源码工程)

前言 在部分场景搭建中需要整齐摆放一些物品&#xff08;如仓库中的货堆、货架等&#xff09;&#xff0c;因为有交互的操作在单个模型上&#xff0c;每次总是手动拖动模型操作起来也是繁琐和劳累。 在这背景下&#xff0c;我编写了一个在运行或者编辑状态下都可以进行一键排序…

JS-元素尺寸与位置

通过js的方式&#xff0c;得到元素在页面中的位置 获取宽高 元素.offsetWidth 元素.offsetHeight 1&#xff09;获取元素的自身宽高、包括元素自身设置的宽高paddingborder 2&#xff09;获取出来的是数值&#xff0c;方便计算 3&#xff09;注意&#xff1a;获取的是可视…

Python项目——搞怪小程序(PySide6+Pyinstaller)

1、介绍 使用python编写一个小程序&#xff0c;回答你是猪吗。 点击“是”提交&#xff0c;弹窗并退出。 点击“不是”提交&#xff0c;等待5秒&#xff0c;重新选择。 并且隐藏了关闭按钮。 2、实现 新建一个项目。 2.1、设计UI 使用Qt designer设计一个UI界面&#xff0c…

C#,入门教程(20)——列表(List)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(19)——循环语句&#xff08;for&#xff0c;while&#xff0c;foreach&#xff09;的基础知识https://blog.csdn.net/beijinghorn/article/details/124060844 List顾名思义就是数据列表&#xff0c;区别于数据数组&#xff08;arr…

WGAN损失函数解读

WGAN是Wasserstein GAN 解读

【大数据Hive】hive 行列转换使用详解

目录 一、前言 二、使用场景介绍 2.1 使用场景1 2.2 使用场景2 三、多行转多列 3.1 case when 函数 语法一 语法二 操作演示 3.2 多行转多列操作演示 四、多行转单列 4.1 concat函数 语法 4.2 concat_ws函数 语法 4.3 collect_list函数 语法 4.4 collect_set函…

dpwwn:02

靶场下载地址 https://download.vulnhub.com/dpwwn/dpwwn-02.zip 环境配置 当打开此虚拟机环境的时候&#xff0c;可能会出现&#xff1a;当前硬件版本不支持设备“sata”。然后启动失败的情况~ 解决办法参考&#xff1a;https://www.cnblogs.com/yaodun55/p/16434468.html …

x-cmd pkg | fanyi - 命令行中英文翻译工具

目录 简介首次用户功能特点竞品和相关作品进一步探索 简介 fanyi 是命令行翻译工具&#xff0c;翻译数据来源于 icba.com 和 fanyi.youdao.com&#xff0c;仅支持中英文互译。支持 ChatGPT&#xff0c;可通过设置 OpenAI API 密钥以启用 ChatGPT 翻译。 注意&#xff1a;在 L…

Flink SQL

Flink SQL 来源&#xff1a;B站尚硅谷 sql-client准备 Table API和SQL是最上层的API&#xff0c;在Flink中这两种API被集成在一起&#xff0c;SQL执行的对象也是Flink中的表&#xff08;Table&#xff09;&#xff0c;所以我们一般会认为它们是一体的。Flink是批流统一的处理…

本地运行LlaMA 2的简易指南

大家好&#xff0c;像LLaMA 2这样的新开源模型已经变得相当先进&#xff0c;并且可以免费使用。可以在商业上使用它们&#xff0c;也可以根据自己的数据进行微调&#xff0c;以开发专业版本。凭借其易用性&#xff0c;现在可以在自己的设备上本地运行它们。 本文将介绍如何下载…

numpy数组的max、min、argmax和argmin计算方法

numpy数组的max、min、argmax和argmin计算方法 官方对numpy.max和numpy.min的说明 numpy.max 参考官方的理解 数组&#xff1a; 24611529 import numpy as npif __name__ __main__:a np.array([[2, 4, 6, 1], [1, 5, 2, 9]])print(a)print(np.argmax(a, axis0)) # ax…

Java医院信息管理系统

技术框架&#xff1a; springboot shiro layui jquery thymeleaf nginx 有需要的可以联系我。 运行环境&#xff1a; jdk8 mysql IntelliJ IDEA maven项目功能&#xff1a; 本项目是用springbootlayuishiro写的医院管理系统&#xff0c;系统的业务比较复杂&#x…

11 - PXC集群|MySQL存储引擎

PXC集群&#xff5c;MySQL存储引擎 数据库系列文章PXC集群配置集群测试集群 MySQL存储引擎存储引擎介绍mysql服务体系结构mysql服务的工作过程处理查询访问的工作过程处理存储insert访问的工作过程 什么是搜索引擎 存储引擎管理查看存储引擎修改存储引擎 存储引擎特点myisam存储…

canvas能压缩图片?

之前写过一篇使用命令行工具压缩图片的博文&#xff1a;使用yx-tiny命令行工具进行图片压缩&#xff0c;大家感兴趣可以去瞅一眼。 这篇简单说一下使用canvas压缩图片 其实思路很简单&#xff0c;我们选择了图片之后&#xff0c;会获取到对应的文件流对象&#xff0c;然后我们…

jvm复习,深入理解java虚拟机一:运行时数据区域

程序计数器&#xff08;Program Counter Register&#xff09; 它是程序控制流的指示器&#xff0c;简单来说&#xff0c;为了线程切换后能恢复到正确的执行位置&#xff0c;每条线程都需要有一个独立的程序计数器 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xf…

【LeetCode每日一题】2809. 使数组和小于等于 x 的最少时间

2024-1-19 文章目录 [2809. 使数组和小于等于 x 的最少时间](https://leetcode.cn/problems/minimum-time-to-make-array-sum-at-most-x/)思路&#xff1a; 2809. 使数组和小于等于 x 的最少时间 思路&#xff1a; 获取两个列表的长度n&#xff0c;并初始化一个二维数组f&…

一种更快的Kmeans原理与实现

普通的k-means实现大多需要多轮迭代,一轮需要O(n * k)的复杂度,其中n是数据量,k是聚类的数量。观察到大部分地方的标准均值中的大多数距离计算都是冗余的。 所以Elkan-Kmeans通过三角不等式来优化这一过程,减少无效计算。 困难在于三角不等式给出了上界,但我们需要下界以…

我在提交代码的时候突然发现别人刚才提交了一点代码,我没有拉取导致问题,请问怎么解决

问: 回答: 问: 我跟随输入git pull ,然后又以下提示: Merge branch systemPower_dev of https://xxxx.com into xxxx_dev # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. …