关键词:
【中文标题】Rust 所有权问题【英文标题】:Rust ownership issues 【发布时间】:2021-01-29 16:10:51 【问题描述】:我对 Rust 很陌生,我主要是 C#、javascript 和 python 开发人员,所以我喜欢以 OOP 方式处理事情,但是我仍然无法理解 rust 的所有权。尤其是在 OOP 方面。
我正在编写一个 TCP 服务器。我有一个包含连接(流)的结构,我使用 mio crate 异步读取套接字。我明白错误告诉我什么,但我不知道如何解决它。我尝试将 read_message 方法更改为一个函数(没有对 self 的引用),它起作用了,但问题是我需要从结构访问连接和诸如此类的东西(例如,在套接字之间中继消息),所以这个解决方法在以后的版本中是不合理的。是否有简单的解决方法,或者设计本身存在缺陷?
这是一个显示我的问题的 sn-p:
let sock = self.connections.get_mut(&token).unwrap();
loop
match sock.read(&mut msg_type)
Ok(_) =>
self.read_message(msg_type[0], token);
fn read_message(&mut self, msg_type: u8, token: Token)
let sock = self.connections.get_mut(&token).unwrap();
let msg_type = num::FromPrimitive::from_u8(msg_type);
match msg_type
Some(MsgType::RequestIps) =>
let decoded: MsgTypes::Announce = bincode::deserialize_from(sock).unwrap();
println!("Public Key: ", decoded.public_key);
_ => unreachable!()
我得到的错误如下:
【问题讨论】:
【参考方案1】:您在sock
上持有一个可变借用,它是self
的一部分,此时您尝试调用self.read_message
。由于您指出 read_message
需要对所有 self
进行可变访问,因此您需要确保此时您不再对 sock
进行可变借用。
幸运的是,感谢 Rust 2018 中的非词法生命周期,这并不难做到;只需在循环内获取sock
:
loop
let sock = self.connections.get_mut(&token).unwrap();
match sock.read(&mut msg_type)
Ok(_) =>
self.read_message(msg_type[0], token);
假设sock.read
没有返回任何在sock
上持有借用的东西,这应该让sock
上的可变借用在调用self.read_message
之前被释放。它需要在下一次迭代中重新获取,但鉴于您正在执行网络 I/O,单个 HashMap
(?) 访问的相对性能损失应该可以忽略不计。
(由于缺少可编译的最小示例,我无法对此进行测试。)
【讨论】:
非常感谢。尽管缺乏适当的例子,但您完全理解我的问题。Rust 如何知道哪些类型拥有资源?
...指向某个堆分配的内存时,我假设Rust已经“硬编码”了所有权知识,因此当通过调用某个函数来转移所有权时,资源会移动并且函数中的参数是新的所有者。但是,例如,矢量如何发生这种情况?它们也“拥有”自己的资源,... 查看详情
如何将值的所有权从 Rust 转移到 C 代码?
】如何将值的所有权从Rust转移到C代码?【英文标题】:HowtotransferownershipofavaluetoCcodefromRust?【发布时间】:2017-07-2006:51:53【问题描述】:我正在尝试使用FFI编写一些Rust代码,其中涉及C获取结构的所有权:fnsome_function()letc=SomeStruc... 查看详情
rust语言特性之所有权
新年开工,开启work&study模式,接着来学习RUST语言。作为一名C/C++程序员,C/C++语言中的指针是使用得最爽的,几乎无所不能,各种奇技淫巧也层出不穷。但C/C++语言中最折磨人的也是指针... 查看详情
如何迭代 Rust 中序列的所有唯一排列?
...quepermutationsofasequenceinRust?【发布时间】:2020-05-1308:10:29【问题描述】:给定一个值列表,例如vec![0,0,1,2],我想创建一个迭代器来生成其所有唯一排列。也就是说,[0,0,1,2][0,0,2,1][0,1,0,2][0,1,2,0][0,2,0,1][0,2,1,0][1, 查看详情
新手眼中的rust所有权规则(代码片段)
新手眼中的Rust所有权规则如果你有关注本人博客,那么很明显,从今年年初开始,我便开始学习Rust。此文与之前风格略有不同,旨在总结阅读Rust书籍时遇到的要点。到目前为止,它包含了我对Rust所有权规则的所有理解。Rust的... 查看详情
rust和go该如何选择
为了内存安全引入所有权概念,为了圆所有权这个坑,引入生命周期,各种BOX。艰难的圆着所有权的坑,因此在rust群里经常谈论的大部分是语法问题,这是其他所有语言都不常见的。虽然一次编译完就可以安... 查看详情
rust和go该如何选择
为了内存安全引入所有权概念,为了圆所有权这个坑,引入生命周期,各种BOX。艰难的圆着所有权的坑,因此在rust群里经常谈论的大部分是语法问题,这是其他所有语言都不常见的。虽然一次编译完就可以安... 查看详情
rust所有权
所有权规则Rust中的每一个值都有一个被称为其所有者(owner)的变量。值在任一时刻有且只有一个所有者。当所有者(变量)离开作用域,这个值将被丢弃。引用和Copy特性赋值过程:包括变量赋值,函数传参,函数返回如果类... 查看详情
怎样才能强制 Rust 获得分配的内存的所有权,而不是通过其安全方法分配的内存?
】怎样才能强制Rust获得分配的内存的所有权,而不是通过其安全方法分配的内存?【英文标题】:HowcanoneforceRusttotakeownershipofmemoryallocatedotherthanbyitssafemethods?【发布时间】:2019-07-1721:30:41【问题描述】:WillCrichton在2018年2月题为... 查看详情
rust所有权语义模型
首发于知乎专栏本文试图从语义角度来解释Rust所有权的概念,以便帮助降低Rust的学习曲线。编程语言的内存管理,大概可以分为自动和手动两种。自动管理就是用GC(垃圾回收)来自动管理内存,像Java、Ruby、Golang、Elixir等语言... 查看详情
rust所有权进阶部分
为了演示所有权功能,我们需要一些复杂的数据类型,之前介绍的类型都是存储在栈上的并且当离开作用域就被移除栈,不过我们需要一个存储在堆上的数据来探索Rust是如何知道该在何时清理数据的。这里使用String作... 查看详情
rust和go该如何选择
为了内存安全引入所有权概念,为了圆所有权这个坑,引入生命周期,各种BOX。艰难的圆着所有权的坑,因此在rust群里经常谈论的大部分是语法问题,这是其他所有语言都不常见的。虽然一次编译完就可以安... 查看详情
rust从入门到精通10-所有权
在介绍rust所有权时,我们先介绍内存管理的一些基础概念。1、堆和栈一个进程在执行的时候,它所占用的内存虚拟空间一般被分割为好几个区域,我们称为”段“(Segment)。常见的几个段如下:①、代码段:编译后的机器码存... 查看详情
rust学习内存安全探秘:变量的所有权引用与借用
...能轻松和其他语言集成。•可靠性-Rust丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。•生产力-Rust拥有出色的文档、友好的编译器和清晰的错误提示信息,还集成了一流的... 查看详情
rust语言教程-从熟悉的部分开始(代码片段)
Rust语言教程(2)-从熟悉的部分开始虽然有默认不变性还有所有权的问题让Rust一上来用起来有些不同,但是其实大部分语法特点还是我们所熟悉的。我们没必要上来就跟自己死磕,可以先从我们熟悉的部分开始学习。一般... 查看详情
如何在 Rust 中打印变量并让它显示有关该变量的所有内容,例如 Ruby 的 .inspect?
...thatvariable,likeRuby\'s.inspect?【发布时间】:2016-12-2615:41:18【问题描述】:usestd::collections::HashMap;fnmain()letmuthash=H 查看详情
rust学习笔记1.基础语法(代码片段)
...体的语句和表达式函数返回值7、条件语句8、循环语句9、所有权Rust的所有权内存的分配变量与数据交互方式移动克隆垂悬引用10、切片11、结构体12、枚举类match语法Option枚举类iflet语法13、生命周期生命周期注释函数的生命周期... 查看详情
杂记rust的destructuringbinding(反结构化绑定)与ownership(所有权)(代码片段)
起因看rustbyexample看得我想睡觉...突然遇到个关于反结构化绑定的奇怪的特性:structPair(Box<i32>,Box<i32>);implPairfndestroy(self)letPair(first,second)=self;println!("DestroyingPair(,)",first,second);fnmain()letpair=Pair(Box::new(1),Box::new(2));pair.d... 查看详情