首页 > 其他分享 >Rust错误案例:error[E0716]: temporary value dropped while borrowed

Rust错误案例:error[E0716]: temporary value dropped while borrowed

时间:2023-11-19 19:14:22浏览次数:34  
标签:borrowed temporary ok 临时 value 引用 entry path folder

原因

出现error[E0716]: temporary value dropped while borrowed的情况往往是因为错误地将引用绑定在了临时变量上,在每行代码结尾的分号;处,临时变量释放导致引用的错误绑定。

由于临时变量多出现于函数编程中,因此该问题多发于连续调用函数。

简短案例

// entry: PathBuf
let folder_path = entry.path().parent().ok_or_else(|| anyhow!("No folder path"))?
fs::create_dir(folder_path).expect("Error while creating dir");

以上代码中会出现error[E0716]: temporary value dropped while borrowed

这是因为,在 Rust 中,当你调用一个方法或函数,方法的返回值通常是一个临时值,除非它被绑定到一个变量上。这个临时值只在当前的语句中有效,也就是说,在分号;到达之前,它都是有效的。

一旦当前语句执行完毕,所有的临时值都会被立即丢弃(除非它们被移动或借用到了另一个生命周期更长的地方)。

看这两行代码执行中发生的事:

  1. entry.path() 调用返回了一个临时的 PathBuf 对象。
  2. 然后立即在这个临时的 PathBuf 对象上调用了 parent() 方法,它返回了一个指向 Path 的临时引用,即 Option<&Path>。
  3. 接着在这个 Option<&Path> 上调用 ok_or_else,如果 Option 是 Some,它就会返回里面的值,如果是 None,它会调用闭包来产生一个错误值。

问题就出在第三步。如果 parent() 返回 None,ok_or_else 将会调用闭包来创建一个 Err,这是没问题的,因为 Err 里面的值是立即创建的。但如果 parent() 返回 Some,ok_or_else 试图直接返回一个引用(&Path),这个引用指向的是 entry.path() 的结果,这是一个临时值。

在 ok_or_else 调用结束后,这个临时值(PathBuf 对象)会被丢弃,但你在 let folder_path 中尝试将一个引用赋值给 folder_path 变量,这个引用指向的内容却在它能被使用之前就被销毁了。

所以,当在下一行代码使用 folder_pathfolder_path引用了一个已经不存在的对象,这违反了 Rust 的借用规则:你不能拥有指向已经被销毁数据的引用。这是 Rust 的所有权和生命周期特性的一部分,确保了引用的安全性和数据的有效性。

正确的做法是将entry.path()返回值绑定在一个变量中,即在引用前延长其生命周期:

let tmp_var = entry.path(); // 通过临时变量来延长entry.path()返回的&PathBuf生命周期,确保在上下文中有足够长的生命周期
let folder_path = tmp_var.parent().ok_or_else(|| anyhow!("No folder path"))?
fs::create_dir(folder_path).expect("Error while creating dir");

标签:borrowed,temporary,ok,临时,value,引用,entry,path,folder
From: https://www.cnblogs.com/KLangHu/p/17842406.html

相关文章

  • SpringBoot使用@Value获取不到值的问题
    背景在一次SpringBoot项目改造为Cloud的过程中,使用Nacos作为配置中心获取属性,改造后程序启动报错,查看日志,定位到代码:解决方案如果了解Bean的生命周期的同学应该知道,Spring在创建Bean的时候,会使用无参构造函数去初始化一个Bean,@Value这个阶段是属于依赖注入,是在初始化之后的,所......
  • 无涯教程-Dart - Optional Parameters with Default Values函数
    默认情况下,还可以为函数参数分配值,但是,此类参数也可以是显式传递的值。语法function_name(param1,{param2=default_value}){//......}示例voidmain(){test_param(123);}voidtest_param(n1,{s1:12}){print(n1);print(s1);}它应该返回......
  • HashMap集合的map.values()返回的Collection集合执行add方法报空指针问题
    一、方法1、privateCollection<String>setPermissionTenant(List<SysPermission>ls,inttenantId){//循环两次第一次设置ID和tenantId第二次设置pidMap<String,String>map=newHashMap<>();for(SysPermissionp:ls){......
  • Python反转字典的key和value
    1.遍历m={'a':1,'b':2,'c':3}n={}fork,vinm.items():n[v]=kprint(n)2.字典推导式m={'a':1,'b':2,'c':3}n={v:kfork,vinm.items()}print(n)3.使用zip函数m={'a'......
  • CoreFX中Dictionary<TKey, TValue>的源码解读
    无论是实际的项目中,还是在我们学习的过程中,都会重点的应用到Dictionary<TKey,TValue>这个存储类型。每次对Dictionary<TKey,TValue>的添加都包含一个值和与其关联的键,使用键检索值的速度非常快,接近O(1),因为 Dictionary<TKey,TValue>类是作为哈希表实现的。首先我们来......
  • selenium报错result.webdriverValue.value
    1.示例代码fromseleniumimportwebdriverdriver=webdriver.Chrome()driver.get('http://124.223.30.31:xxx/forum.php')driver.find_element('id','ls_username').send_keys('admin')端口我匿了这个代码是没有问题的,任意其他代码在当前的环境下都是会出现这个错......
  • A potentially dangerous Request.Form value was detected from the client
    ApotentiallydangerousRequest.Formvaluewasdetectedfromtheclient解决方案一:在.aspx文件头中加入这句:<%@PagevalidateRequest="false" %>解决方案二:修改web.config文件:<configuration> <system.web>   <pagesvalidateRequest="fals......
  • redis 类型Hash 中value存储空间大小
    在Redis中,Hash数据类型的存储空间大小取决于存储在Hash中的键值对的数量以及每个键值对的键和值的大小。Redis内部会根据实际存储的数据进行动态分配内存,因此存储空间大小是可变的。下面是关于Hash数据类型中value存储空间大小的一些考虑因素:键值对数量:Hash中的键值对数量是主要影......
  • 无涯教程-批处理 - Functions with Return Values函数
    函数可以通过简单地传递变量名称来使用返回值,这些变量名称将在调用函数时保存返回值,如下所示Call:function_namevalue1,value2…valuen使用set命令和tilde(〜)字符以及参数的位置编号在函数中设置返回值。下面的示例演示如何使用返回值调用函数。@echooffSETLOCALCALL......
  • LeetCode #1131 Maximum of Absolute Value Expression 绝对值表达式的最大值
    安装Flutter环境首先配置flutter3开发环境,照着官方教程傻瓜式安装即可。>>安装和环境配置|Flutter中文文档|Flutter中文开发者网站注意在国内网络环境下需要进行一些额外的环境配置:>>在中国网络环境下使用Flutter|Flutter中文文档|Flutter中文开发者网站Description......