borrow-checker 相关问题

借用检查器是指Rust编程语言使用的所有权概念的编译时分析。此标记应用于相关问题和错误。

如何解决由于过滤 read_dir 输出而“无法移出借用的内容”?

我尝试使用 read_dir 读取目录的内容,然后仅过滤文件: 让 xs = std::fs::read_dir(".")? .filter(|r_entry| { r_entry.and_then(|条目| { ...

回答 1 投票 0

如何从方法中修改并返回 self?

我有一个结构和各自的实现: pub 结构部门 { 酒吧 ID:字符串, pub linked_accounts:Vec, } 实施部门{ pub fn add_account(&mut self, ...

回答 2 投票 0

如何在不移动 Rust 的情况下反转列表

我正在尝试编写一个简单的函数来检测回文。我找不到一种方法来避免在反转时移动 nums,所以我最终得到了以下结果: fn is_palindrome(num: String) -> boo...

回答 1 投票 0

如何以消耗第二个的方式组合 Vec 中的成对项目?

我遇到了一个典型的借用检查器错误,我希望人们可以向我展示一些惯用的解决方案。下面请看一个微型示例。 #[导出(调试)] pub 结构单元 { 倍性:u32, } 实现单元格...

回答 2 投票 0

不能借用“cells”作为不可变的,因为它也被借用为可变的

我遇到了一个典型的借用检查器错误,我希望人们可以向我展示一些惯用的解决方案。下面请看一个微型示例。 #[导出(调试)] pub 结构单元 { 倍性:u32, } 实现单元格...

回答 1 投票 0

如何从geo_types检查几何类型

我是 Rust 新手,我仍然在与 geo_types 箱中的 TryFrom 函数相结合的借用概念上苦苦挣扎。 我基本上想根据实际情况做不同的事情

回答 1 投票 0

在 Rust 中,在需要引用 self 的结构体方法中使用闭包作为 while 循环条件

我有一个简单的结构解析器 pub 结构解析器 { 位置:使用, 输入:字符串, } 我正在尝试构建一个 markdown 解析器,并且有一个方法 parse_md_line 包含一个 while 循环,我......

回答 1 投票 0

可变引用的生命周期

我正在学习 Rust 中的借用概念。所以,在这里我发现了一些不全面的东西。 结构体A(i32); fn 主() { 让 mut x = A(5); 让z; // 第一个块 { 让 t = &mut ...

回答 1 投票 0

无法借用“Rc”中的可变数据

我一直在用 Rust 编写光线追踪器,但遇到了一个问题。我定义了以下结构: pub 结构 HitRecord{ 垫子:Rc, ... } 母亲...

回答 1 投票 0

无法分配,因为是临时借用的

我有以下代码,具有两个几乎相同的功能。其中之一无法编译。 结构节点{ 酒吧数据:i32, 酒吧下一个:选项>>, 酒吧上一页:

回答 1 投票 0

在 Rust 中处理大型可变结构的最佳方法是什么?

这是我的问题的简化视图: 结构游戏{ 当前玩家:u8, 玩家:Vec, 单位:Vec, } fn update(游戏: &mut 游戏) { 对于游戏中的单位.u...

回答 1 投票 0

将从结构借用的值传递回结构上的方法

我是 Rust 新手,尝试从 python 移植一些代码。我想询问一个特征的对象集合,对其进行一些过滤,然后将对象传递回该特征的方法,m...

回答 1 投票 0

如何将带有嵌套借用/NLL 的 Rust 代码提取到函数中

我有一个很大的枚举,我正在其中修改数据。匹配案例变得难以处理,所以我想将它们提取到一个单独的函数中。然而,由于

回答 1 投票 0

可变引用有移动语义吗?

fn main() { 让 mut name = String::from("Charlie"); 让 x = &mut 名称; 设 y = x; // x 已移动 说你好(y); 说你好(y); // 但 y 还没有...

回答 1 投票 0

借用 Rust

我对 Rust 相当陌生。因此我对借用检查器等没有这么深入的理解。我已经用 C++ 做了一个编译器,所以我尝试在 Rust 中做同样的事情,因为它似乎是一个......

回答 1 投票 0

结构初始化取决于移动借用值

我正在尝试初始化一个如下所示的结构: 结构体UsbCommandPort<'a> { 串行:串行端口<'a, UsbBus>, usb_dev: USB设备<'a, UsbBus>, } ...

回答 1 投票 0

结构初始化取决于移动借用值

我正在尝试初始化一个如下所示的结构: 结构体UsbCommandPort<'a> { 串行:串行端口<'a, UsbBus>, usb_dev: USB设备<'a, UsbBus>, } ...

回答 1 投票 0

Rust 从可变引用中重新借用共享引用

我是 Rust 新手,并试图理解为什么对已借用元素的数据结构的可变引用似乎可以在同一生命周期内再次使用来借用另一个元素...

回答 1 投票 0

Rust 编译器坚持要求我传递一个拥有的值,但看起来它位于“&”引用后面

我有一个如下所示的结构。 结构测试{ 场:Vec, } 我将此结构的引用作为函数参数传递。 我有第二个函数需要 &Vec 我有一个如下所示的结构。 struct Test { field: Vec<String>, } 我将此结构的引用作为函数参数传递。 我有第二个函数需要 &Vec<String>。 fn main() { let obj = Test { field: vec![] }; takes_ref_to_struct(&obj); } fn takes_ref_to_struct(obj: &Test) { takes_ref_to_field(obj.field); } fn takes_ref_to_field(field: &Vec<String>) {} 由于以下错误,此用法将无法编译: error[E0308]: mismatched types --> src/main.rs:11:24 | 11 | takes_ref_to_field(obj.field); | ------------------ ^^^^^^^^^ expected `&Vec<String>`, found `Vec<String>` | | | arguments to this function are incorrect | = note: expected reference `&Vec<String>` found struct `Vec<String>` note: function defined here --> src/main.rs:14:4 | 14 | fn takes_ref_to_field(field: &Vec<String>) {} | ^^^^^^^^^^^^^^^^^^ ------------------- help: consider borrowing here | 11 | takes_ref_to_field(&obj.field); 显然我可以添加建议的借用,但为什么这是必要的?如果我尝试改变这个领域 fn takes_ref_to_struct(obj: &Test) { obj.field.clear(); } 编译器按预期进行抱怨 error[E0596]: cannot borrow `obj.field` as mutable, as it is behind a `&` reference --> src/main.rs:11:5 | 11 | obj.field.clear(); | ^^^^^^^^^^^^^^^^^ `obj` is a `&` reference, so the data it refers to cannot be borrowed as mutable Rust 是一种严格类型的语言。虽然编译器确实会自动执行一些转换,例如 with self,但一般来说,您有责任在调用函数时提供所需类型的值。 当您有引用时编译器不会自动执行此操作的原因有两个。首先,如果您did拥有该对象,则移动该字段是有效的。当拥有的对象是引用时自动添加引用会令人困惑,但当它被拥有时却不会。规则、可靠的行为对于人类理解、工具易用性和跨实现兼容性来说非常重要。由于缺乏一致的行为,Perl 5 中的可靠工具(例如代码格式化程序)变得非常困难,并且多种实现实际上是不可能的。 其次,编译器直到编译的这个阶段之后才评估所有权和借用。类型检查发生在借用检查之前,因此编译器此时尚未评估借用和所有权规则。在类型全部解析之前,进行借用和所有权检查将非常困难,因为 Rust 编译器需要推断和计算类型才能有效地进行借用检查,因此实际上您需要首先确保类型正确。

回答 1 投票 0

Rust,如何从 Rc<RefCell<T>> 中复制出内部值并返回?

简介:我是 Rust 新手,所以我决定通过实现双链表来练习。出于调试目的,我实现了 get() 方法,但未能从 Rc 中复制出值 简介:我是 Rust 新手,所以我决定通过实现双链表来练习。出于调试目的,我实现了 get() 方法,但未能从 Rc<RefCell<_>> 中复制值。 (抱歉问了个愚蠢的问题) 问题:我试图在Result<T, &'static str>中返回一个.get(),其中T是节点中存储的数据类型,&str是错误消息字符串。借用检查器告诉我,我无法返回对方法内变量的引用,因此我尝试将内部值复制出来并返回它,但失败了。 源代码: use std::{rc::Rc, cell::RefCell}; struct Node<T> { data: Option<T>, prev: Option<Rc<RefCell<Node<T>>>>, next: Option<Rc<RefCell<Node<T>>>>, } impl<T> Node<T> { /// Instantiate a new dummy node. /// This node is used to mark the start and end of the list. /// It is not counted in the size of the list. fn new() -> Self { Node { data: None, prev: None, next: None, } } /// Instantiate a new content node. /// This node is used to store data. /// It is counted in the size of the list. fn from(data: T) -> Self { Node { data: Some(data), prev: None, next: None, } } } struct List<T> { head: Rc<RefCell<Node<T>>>, tail: Rc<RefCell<Node<T>>>, size: usize, } impl<T> List<T> { pub fn new() -> Self { let head = Rc::new(RefCell::new(Node::new())); let tail = Rc::new(RefCell::new(Node::new())); head.borrow_mut().next = Some(Rc::clone(&tail)); tail.borrow_mut().prev = Some(Rc::clone(&head)); List { head, tail, size: 0 } } pub fn prepend(&self, data: T) { let node = Rc::new(RefCell::new(Node::from(data))); let mut head = self.head.borrow_mut(); node.borrow_mut().next = Some(head.next.take().unwrap()); node.borrow_mut().prev = Some(Rc::clone(&self.head)); head.next = Some(Rc::clone(&node)); if let Some(next) = node.borrow().next.as_ref() { next.borrow_mut().prev = Some(Rc::clone(&node)); }; } pub fn append(&self, data: T) { let node = Rc::new(RefCell::new(Node::from(data))); let mut tail = self.tail.borrow_mut(); node.borrow_mut().prev = Some(Rc::clone(&tail.prev.take().unwrap())); node.borrow_mut().next = Some(Rc::clone(&self.tail)); tail.prev = Some(Rc::clone(&node)); if let Some(prev) = node.borrow().prev.as_ref() { prev.borrow_mut().next = Some(Rc::clone(&node)); }; } pub fn get(&self, index: isize) -> Result<T, &'static str> { let mut current: Rc<RefCell<Node<T>>> = Rc::clone(self.head.borrow().next.as_ref().unwrap()); for _ in 0..index { let tmp = Rc::clone(current.borrow().next.as_ref().ok_or("Index out of range")?); current = tmp; } let result = current.borrow().data.as_ref().ok_or("Index out of range")?; // error[E0716] Ok(*result) // error[E0507] } } /* error[E0716]: temporary value dropped while borrowed --> src\linked.rs:74:22 | 74 | let result = current.borrow().data.as_ref().ok_or("Index out of range")?; | ^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary value which is freed while still in use 75 | Ok(*result) | ------- borrow later used here | help: consider using a `let` binding to create a longer lived value | 74 ~ let binding = current.borrow(); 75 ~ let result = binding.data.as_ref().ok_or("Index out of range")?; | error[E0507]: cannot move out of `*result` which is behind a shared reference --> src\linked.rs:75:12 | 75 | Ok(*result) | ^^^^^^^ move occurs because `*result` has type `T`, which does not implement the `Copy` trait */ 我已经尝试过: 这篇关于引用价值的文章,但这就是我正在尝试做的事情,但失败了。 这篇关于修改RefCell的文章,但这没有帮助。我试图归还它,而不是改变它。 这篇文章是关于如何借用RefCell,但我无法归还借用的价值,因为借用的Rc是短暂的(但内在价值不是)。 这篇关于如何在 RefCell 中返回某些内容的文章和 这篇关于如何使用 .map() 返回它的文章,但是当我尝试使用 .into() 时,编译器说“特征绑定不满足”并且如果我删除 .into(),借阅检查员会抱怨“无法搬出”。 这篇关于使用Rc::try_unwarp()的文章,但它不起作用,因为内部数据有多个所有者。 另外:我可能做错了,如果其中一篇文章解决了我的问题,但我没有以正确的方式实现它,请原谅我,并请教我如何正确地做到这一点。非常感谢。 你不知道。 如果值为Copy,则可以复制。如果是Clone,就可以克隆它。但如果不是,或者克隆成本太高? 你运气不好。 内部可变性(如 RefCell)对于 API 来说是不利的。它往往会跨越 API 边界传播,有时甚至完全阻止您实现它们。 (有时)在实现内部很好,但不是因为它泄漏。 当然,有一种正确的方法来实现双向链表(因为 std 有一个),但是这种正确的方法需要不安全的代码。当您已经掌握 Rust 后,您可能想返回它作为练习。请务必阅读使用太多的链表学习 Rust。

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.