Rust 所有权问题

     2023-02-16     208

关键词:

【中文标题】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... 查看详情