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; 配置步骤简单明…

【算法详解】力扣88.合并两个有序数组

一、题目介绍 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xf…

动态规划基础(二)最长公共子序列 LCS

讲解求两个串中最长的公共的子序列长度或输出子序列等 poj1458 题目大意 给定两个字符串&#xff0c;要求输出两个字符串中最长公共子序列长度 思路 我们定义 a [ i ] [ j ] a[i][j] a[i][j]为&#xff0c;当字串 s t r 1 str1 str1到 i i i位置&#xff0c;字串 s t r 2 s…

采埃孚: 优化1/4员工;苹果Vision Pro开抢,黄牛9万一台 ;招商银行:2023年净利润1466亿元

今日精选 • 采埃孚: 优化1/4员工• 苹果Vision Pro开抢&#xff0c;黄牛9万一台• 招商银行&#xff1a;2023年净利润1466亿元&#xff0c;同比增长6.22% 科技动态 • OpenAI CEO 拟募集百亿级美元&#xff0c;建立 AI 芯片工厂网络以满足需求• 中西医结合“数智岐黄”大模…

【接上篇】二、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;我编写了一个在运行或者编辑状态下都可以进行一键排序…

C#设计模式教程(10):装饰器模式

装饰器模式的定义 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许用户在不修改现有对象结构的情况下,动态地给一个对象添加额外的职责。这种模式创建了一个装饰类,用来包装原有的类。 这种模式创建了一个装饰类,用于包装原有的类,并在保持类方法签名完整性…

JS-元素尺寸与位置

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

C++中的指针、引用;左值、右值;左值引用、右值引用

一、指针、引用 引用指的是为已经创建的对象重新起一个名字。创建引用的时候&#xff0c;编译器只是将这个别名绑定到引用的对象上。 对象名提供了一种直接访问数据的方式&#xff0c;因为对象名本质上是数据所在的内存地址空间的一个地址映射。 引用提供了一种简介访问数据…

在 Python 中实现语音合成的四种方法

1 离线合成 pytts 配置环境 $ apt-get update $ apt-get install espeak $ pip install pyttsx3 $ apt-get install ffmpeg $ apt-get install alsa-utils运行程序 import pyttsx3engine pyttsx3.init() engine.setProperty(rate, 150) engine.setProperty(volume, 0.7)tex…

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…

redis复制和分区:主从复制、哨兵模式和集群模式

概述 在 Redis 中&#xff0c;复制和分区是用于数据冗余和性能扩展的关键特性。以下是主从复制、哨兵模式和集群模式的工作原理的简要概述&#xff1a; 主从复制 (Replication) 基本概念&#xff1a;Redis 的主从复制功能允许多个 Redis 服务器具有相同的数据副本。这在读取操…

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函…

《设计模式的艺术》笔记 - 命令模式

介绍 命令模式将一个请求封装为一个对象&#xff0c;从而可用不同的请求对客户进行参数化&#xff1b;对请求排队或者记录请求日志&#xff0c;以及支持可撤销的操作。命令模式是一种对象行为模式&#xff0c;其别名为动作模式或事务模式。 实现 myclass.h // // Created by …

数据预处理 matlab 数据质量评估

知乎 数据类型转换等 Mathworks 数据预处理 概念辨析 配对是同一批样本的前后比较&#xff0c;独立是两批不同样本的的比较 独立样本是指我们得到的样本是相互独立的。配对样本就是一个样本中的数据与另一个样本中的数据相对应的两个样本。配对样本可以消除由于样本指定的不公…

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…

QT上位机开发(动态数据采集与监控)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 上位机开发中,有一种类型的应用软件很特殊,它几乎没有什么交互操作,主要的工作就是检测和显示。如果说在此基础上有什么扩展的话,可能就是安全监控和报警。所以,这个上位机软件…