我从概念上理解借用;它们是不被拥有的价值,必须通过借款人丢弃来归还给所有者
这是有道理的,但我实际上不明白参考是什么。我读到 Rust 引用不执行堆分配,但它们实际上也是指针。
如此之多以至于以下代码可以直接将引用转换为原始堆分配的指针:
// owned value
let some_val = 1;
// reference
let some_ref = &some_val;
// pointer
let some_ptr = some_ref as *const i32;
// prints "1 1 1" as expected
unsafe {
println!("{} {} {}", some_val, some_ref, *some_ptr);
}
Run Code Online (Sandbox Code Playgroud)
我的理解哪一部分是错误的?我的假设是指针后面和堆栈分配是互斥的,但我错了吗?告诉我引用不是堆分配的消息来源是错误的吗?
我想第二个问题是问上面的片段中的内存到底是什么样的^
据我的理解,情况如下:
// load const 1 and store as some_val
let mut some_val = 1;
// load 1 onto the stack and invoke do_something
do_something(some_val);
// still load 1 onto the stack and invoke do_something, but ownership is not given to do_something()
do_something(&some_val);
// still load 1 onto the stack and invoke do_something & ownership is not given, but the borrow checker also makes sure that some_val is not mutably borrowed until do_something is done with &mut some_val
do_something(&mut some_val);
// allocate a copy of some_val to the heap, load a raw pointer to the new memory location onto the stack, and invoke do_something on the raw pointer. We still own some_val
do_something(&some_val as *const i32;)
Run Code Online (Sandbox Code Playgroud)
我认为这种理解的某些部分是错误的,希望得到纠正!
我的理解哪一部分是错误的?我的假设是指针后面和堆栈分配是互斥的,但我错了吗?
你的理解是不正确的。指针可以“指向”内存中的任何值,包括堆栈和堆。指针只是内存中的一个地址,存在于堆栈或堆上的值仍然有一个地址。引用只是借用检查器可以推理的指针之上的安全抽象。
我现在将解释你的例子:
// Owned value of `1_i32` on the stack
let some_val = 1;
// Shared (immutable) reference to `some_val`
// Implemented as a `*const i32` pointer holding `some_val` memory address
let some_ref = &some_val;
// Raw pointer to `some_val`, cast from `some_ref`
// Has the same value in memory as `some_ref`
let some_ptr = some_ref as *const i32;
// Invoke do_something, passing `some_val` by value
// Passes the value `1` directly to the function
// Ownership is given, and if the type of `some_val` is not trivially
// copyable, `some_val` will not be accessible to this scope anymore
do_something(some_val);
// Invoke do_something, passing `some_val` by shared reference
// Passes the pointer (memory address) of `some_val` to the function
// Ownership is not given, and do_something is not allowed
// to modify the value held in `some_val`
do_something(&some_val);
// Invoke do_something, passing `some_val` by exclusive reference
// Passes the pointer (memory address) of `some_val` to the function
// Ownership is not given, but do_something is allowed
// to modify the value held in `some_val`
do_something(&mut some_val);
// Invoke do_something, passing `some_val` as a raw `*const` pointer
// Passes the pointer (memory address) of `some_val` to the function
// Ownership is not given, and do_something is not allowed
// to modify the value held in `some_val`
// (but operations on raw pointers, requiring unsafe, are not enforced by the compiler)
do_something(&some_val as *const i32);
Run Code Online (Sandbox Code Playgroud)
在内存中,some_val
可能位于堆栈上的地址(对于 i32 为 4 个字节)0xFFF0
。也将在堆栈上分配,放置在through (64 位系统为 8 个字节)并保存值。并且指针同样可以通过保持相同的值来定位。0xFFF3
some_ref
0xFFE8
0xFFEF
0xFFF0
0xFFE0
0xFFE7
0xFFF0
当然,大多数编译器都会进行优化,因此some_val
实际上可以在寄存器中而不是在堆栈上的内存中,并且使用引用或指向它的指针的任何操作都可以内联以直接使用寄存器。但就心智模型而言,这并不重要。
归档时间: |
|
查看次数: |
206 次 |
最近记录: |