- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我想知道可变引用如何进入方法时,所有的问题都开始了。
let a = &mut x;
a.somemethod(); // value of a should have moved
a.anothermethod(); // but it works.
我用谷歌搜索了很多。 (真的很多)
fn test(&mut a) -> ();
let a = &mut x;
test(a); // what we write in code.
test(&mut *a); // the actual action in code.
所以,我在谷歌上搜索了更多关于“再借”的细节。
let a = &mut x;
let b = &mut *a; // a isn't available from now on
*a = blahblah; // error! no more access allowed for a
*b = blahblah; // I've wrote this code not to confuse you of the lifetime of b. If not mentioned, it always live till the scope ends.
let a = &mut x;
{
let b = &*a;
// *a = blahblah in this scope will throw an error, just like above case.
}
*a = blahblah; // but this works.
好吧。这很有趣。好像
b
不仅借了
x
还有
a
.
&'a *(&'b mut x)
.
x
(这里有一个生命周期 'a),
a
(它有一个生命周期'b)。
let x: i32 = 1; // I wanted to make it clear that x lives in this scope.
let b;
{
let a = &mut x;
b = &mut *a;
}
*b = 0;
但这有效!
&'a mut *&mutx
,不是
&'a mut *&'b mutx
.
mut x
在
&mut *&mutx
的生命周期内不可用也不为什么
mut x
在
&mut *&mutx
的生命周期后重新可用,但是“好吧,让我们这么说吧”。
let x: i32 = 1;
let b;
{
let a = &mut x;
let b = &**&a;
} // error!! a should live longer than b!
生命周期不是简单地依赖于真实数据
b
指的是???
&'a **& &mut x
,不是
&'a **&'b &'c mut x
.
&'a **&'b &mut x
??? (这是我的猜测)。
最佳答案
这是一些很好的问题!我会尽我所能回答那些我能回答的。
Rust Reference 是寻找此类问题答案的好地方,关于 Rust 的更深层语义。
首先,对于您关于方法解析的问题,the Referencesays :
When looking up a method call, the receiver may be automaticallydereferenced or borrowed in order to call a method. This requires amore complex lookup process than for other functions, since there maybe a number of possible methods to call. The following procedure isused:
The first step is to build a list of candidate receiver types. Obtainthese by repeatedly dereferencing the receiverexpression's type, adding each type encountered to the list, thenfinally attempting an unsized coercion at the end, and adding theresult type if that is successful. Then, for each candidate
T
, add&T
and&mut T
to the list immediately afterT
.For instance, if the receiver has type
Box<[i32;2]>
, then thecandidate types will beBox<[i32;2]>
,&Box<[i32;2]>
,&mut Box<[i32;2]>
,[i32; 2]
(by dereferencing),&[i32; 2]
,&mut [i32; 2]
,[i32]
(by unsized coercion),&[i32]
, and finally&mut [i32]
.
&mut T
to&T
&T
or&mut T
to&U
ifT
implementsDeref<Target = U>
&mut T
to&mut U
ifT
implementsDerefMut<Target = U>
&U
和
&mut U
都实现
Deref<Target = U>
, 和
&mut U
还实现了
DerefMut<Target = U>
.因此,第二/第三条规则导致以下强制:
T
是:
&U
&&U
&U
&U
&mut &U
&U
&mut U
&&mut U
&U
&mut U
&mut &mut U
&mut U
let a = &mut x;
let b = &mut *a; // a isn't available from now on
*a = blahblah; // error! no more access allowed for a
*b = blahblah; // I've wrote this code not to confuse you of the lifetime of b. If not mentioned, it always live till the scope ends.
let a = &mut x
, 现在
a
是访问
x
的唯一途径.现在当你写
let b = &mut *a
,它本质上意味着
let b = &mut *(&mut x)
,简化为
let b = &mut x
.
b
可变借用
a
, Rust 不会让你使用
a
直到
b
被摧毁了……或者现在看起来是这样。
let a = &mut x;
{
let b = &*a;
// *a = blahblah in this scope will throw an error, just like above case.
}
*a = blahblah; // but this works.
let b = &*a
变成
let b = &*(&mut x)
,所以
let b = &x
.无论何种引用
b
是,
a
是一个可变引用并且必须是唯一的,所以在
b
之前你不能使用它消失了(超出范围)。
let mut x: i32 = 1; // I wanted to make it clear that x lives in this scope.
let b;
{
let a = &mut x;
b = &mut *a;
}
*b = 0;
let mut x
)。
a
和
b
两者都可变地指向同一个对象,Rust 不会让你使用
a
直到
b
被摧毁。似乎推理应该是,“因为
b
可变地借用了
a
”,但实际上并非如此。通常,
b
实际上会借
a
,这就是像
Box
这样的智能指针的情况。 ,
std::cell::RefMut
等。然而,引用得到特殊处理:Rust 可以分析它们指向的内存。
let b = &mut *a
,
b
实际上并没有借
a
!它只借用数据
a
指着。这种区别以前不相关,但在这里它允许代码编译。
关于rust - 可变引用的再借用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65474162/
编辑备注 由于 Rust(版本:1.42)仍然没有稳定的 ABI ,推荐使用extern (目前相当于extern "C"(将来可能会改变))否则,可能需要重新编译库。 This article解释如
词法分析器/解析器文件位于 here非常大,我不确定它是否适合只检索 Rust 函数列表。也许我自己编写/使用另一个库是更好的选择? 最终目标是创建一种执行管理器。为了上下文化,它将能够读取包装在函数
我试图在 Rust 中展平 Enum 的向量,但我遇到了一些问题: enum Foo { A(i32), B(i32, i32), } fn main() { let vf =
我正在 64 位模式下运行的 Raspberry Pi 3 上使用 Rust 进行裸机编程。我已经实现了一个自旋锁,如下所示: use core::{sync::atomic::{AtomicBool
我无法理解以下示例是如何从 this code 中提炼出来的, 编译: trait A: B {} trait B {} impl B for T where T: A {} struct Foo;
在我写了一些代码和阅读了一些文章之后,我对 Rust 中的移动语义有点困惑,我认为值移动后,它应该被释放,内存应该是无效的。所以我尝试写一些代码来作证。 第一个例子 #[derive(Debug)]
https://doc.rust-lang.org/reference/types/closure.html#capture-modes struct SetVec { set: HashSe
考虑 const-generic 数据结构的经典示例:方矩阵。 struct Matrix { inner: [[T; N]; N] } 我想返回一个结构体,其 const 参数是动态定义的:
以下代码无法编译,因为 x在移动之后使用(因为 x 具有类型 &mut u8 ,它没有实现 Copy 特性) fn main() { let mut a: u8 = 1; let x:
我在玩 Rust,发现了下面的例子: fn main() { let mut x = [3, 4, 5].to_vec(); x; println!("{:?}", x); }
假设一个 Rust 2018 宏定义了一个 async里面的功能。它将使用的语法与 Rust 2015 不兼容。因此,如果您使用 2015 版编译您的 crate,那么宏中的扩展代码不会与它冲突吗?
假设我有一些 Foo 的自定义集合s: struct Bar {} struct Foo { bar: Bar } struct SubList { contents: Vec, }
代码如下: fn inner(x:&'a i32, _y:&'b i32) -> &'b i32 { x } fn main() { let a = 1; { let b
在lifetime_things的定义中,'b的生命周期比'a长,但实际上当我调用这个函数时,x1比y1长,但是这样可以编译成功: //here you could see 'b:'a means
我正在尝试检索 FLTK-RS Widget 周围的 Arc Mutex 包装器的内部值: pub struct ArcWidget(Arc>); impl ArcWidget{ pub
如下代码所示,我想封装一个定时函数,返回一个闭包的结果和执行时间。 use tap::prelude::Pipe; use std::time::{Instant, Duration}; pub fn
我想实现自己的通用容器,这是我正在使用的特征的片段: pub trait MyVec where Self: Default + Clone + IntoIterator, Self:
所需代码: 注释掉的块可以编译并工作,但是我想从嵌套的匹配样式转变为更简洁的函数链 async fn ws_req_resp(msg: String, conn: PgConn) -> Result>
我正在尝试编写一些代码,该代码将生成具有随机值的随机结构。对于结构,我具有以下特征和帮助程序宏: use rand::{thread_rng, Rng}; use std::fmt; pub trai
我有一个带有函数成员的结构: struct Foo { fun: Box, } type FooI = Foo; 这不起作用: error[E0106]: missing lifetime s
我是一名优秀的程序员,十分优秀!