Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

https://rustx-labs.github.io/effective-rust-cn/chapter_1/item8-references&pointer.html 这本书的第8条中 #54

Open
xuejianxinokok opened this issue Sep 9, 2024 · 1 comment

Comments

@xuejianxinokok
Copy link

use std::cell::RefCell;
let rc: RefCell = RefCell::new(42);
let b1 = rc.borrow();

let b2 = rc.borrow();

在其 图片 https://rustx-labs.github.io/effective-rust-cn/images/item8/refcell.svg 中 b1,b2 为什么画成 胖指针? 哪位大佬能解释一下?
image

@yingang
Copy link
Contributor

yingang commented Feb 10, 2025

你好,不是大佬,尝试说一下自己的理解。

我理解这里不管是rc还是b1/b2都不是所谓的胖指针,按这本书时说的,Rust自带的胖指针主要是指切片(slice)和trait对象(trait object)。

上图里体现的更多是RefCell类型和RefCell的borrow()方法返回的Ref类型的内部结构,可以直接对照Rust的源码理解一下。

比如RefCell,borrow属性维护了RefCell的借用状态,BorrowFlag为-1表示有mut借用,为正值则表示有若干个非mut借用,而value属性保存的就是RefCell里的值。

/// A mutable memory location with dynamically checked borrow rules
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RefCell<T: ?Sized> {
    borrow: Cell<BorrowFlag>,
    value: UnsafeCell<T>,
}

RefCell的borrow()方法返回的Ref也是类似,其value属性指向RefCell的value属性,borrow属性则指向RefCell的borrow属性,后者我理解是为了维护RefCell的借用状态而设置的,比如Ref退出作用域时,就可以将borrow属性指向的BorrowFlag减1:

/// Wraps a borrowed reference to a value in a `RefCell` box.
/// A wrapper type for an immutably borrowed value from a `RefCell<T>`.
pub struct Ref<'b, T: ?Sized + 'b> {
    // NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
    // `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
    // `NonNull` is also covariant over `T`, just like we would have with `&T`.
    value: NonNull<T>,
    borrow: BorrowRef<'b>,
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants