什么时候应该使用智能指针?
When should I use smart pointers?
对于 C++,有一个类似的非常流行的 question,但我找不到关于 Rust 的类似现有问题。
那么,Box
、Rc
、Ref
、RefMut
(其他?)在 Rust 中的用例是什么?
问题的重要部分(对我个人而言):什么时候应该使用智能指针而不是引用?
我知道 Rust Book 解释得非常、非常透彻,但我希望能有一个关于这个主题的简明扼要的 "cheatsheet",可能还有书中缺少的一些真实世界的例子。
我给出的简单答案是:尽可能使用引用。不幸的是,了解何时可以取决于对借用检查器的更深入了解,到那时,我想作弊 sheet 将不再有用。但是,一些简单的解释可能会有所帮助。
- 最简单的情况是您有一个明确的所有者,并且将引用向下传递到您调用的函数的堆栈中。此案例仅供参考。
- 如果您拥有同样明确的所有权,但物品是 "large" 或尺寸不确定,您可能需要
Box
。仍然是一个所有者,可能有基于堆栈的借贷。
- 当树中的所有权不明确时,
Rc
或 Arc
将是合适的(使用 Mutex
之类的东西进行共享)。
提到的其他内容(Ref
、RefMut
)具体是关于借用 RefCell
中包含的内容。 Cell
和 RefCell
是可变的容器。
我想说的是,首先尝试只拥有您的物品,并使用借来的引用来传递它。如果您确实需要共享,请查看 Rc
或 Arc
。如果还是不行,再考虑其他的。
同样,Rust Book 的描述非常好,您必须了解借用才能对使用什么有直觉。
What are the use cases for Box
, Rc
, Ref
, RefMut
(others?) in Rust?
好的,我们开始:
Box
,用最简单的话来说,当你有一个对象你想保留在堆上时使用。什么时候用盒子
- 您想own a dynamically sized object
- 您想将对象泄漏到
'static
lifetime
- 您想制作一个 ffi pointer
- 您想recursive types
Rc
在很难决定对象的生命周期时使用。过度使用是懒惰的表现,在某种程度上违背了生命的目的。
例如,Ref
和 RefMut
是由 RefCell
when you try to get access to its contents. A RefCell
will track the borrowing state of its object at runtime instead of compile time, so it is kind of like lifetimes. A general use for this is when you need to have mutable references to many objects in a hashmap 生成的对象。
Arc
is used with either RwLock
(Essentially the same as RefCell
apart from what's below) or Mutex
尝试跨线程边界共享对象时。他们页面上的示例将向您展示如何使用它们以及为什么它们比使用 Rc<RefCell<T>>
模式更重要。
rust 本身还有一些 "smart" 指针,但您必须知道,除非您使用不安全代码或直接使用全局分配器,否则所有内容最终都会取消分配其内容。
这与为什么语言中内置的工具(生命周期)对 Rust 如此重要有关,它们完成了 Rc
和 RefCell
完成的所有工作,但没有性能缺陷,并且还做了 C/C++
没有UB的机会。
对于 C++,有一个类似的非常流行的 question,但我找不到关于 Rust 的类似现有问题。
那么,Box
、Rc
、Ref
、RefMut
(其他?)在 Rust 中的用例是什么?
问题的重要部分(对我个人而言):什么时候应该使用智能指针而不是引用?
我知道 Rust Book 解释得非常、非常透彻,但我希望能有一个关于这个主题的简明扼要的 "cheatsheet",可能还有书中缺少的一些真实世界的例子。
我给出的简单答案是:尽可能使用引用。不幸的是,了解何时可以取决于对借用检查器的更深入了解,到那时,我想作弊 sheet 将不再有用。但是,一些简单的解释可能会有所帮助。
- 最简单的情况是您有一个明确的所有者,并且将引用向下传递到您调用的函数的堆栈中。此案例仅供参考。
- 如果您拥有同样明确的所有权,但物品是 "large" 或尺寸不确定,您可能需要
Box
。仍然是一个所有者,可能有基于堆栈的借贷。 - 当树中的所有权不明确时,
Rc
或Arc
将是合适的(使用Mutex
之类的东西进行共享)。
提到的其他内容(Ref
、RefMut
)具体是关于借用 RefCell
中包含的内容。 Cell
和 RefCell
是可变的容器。
我想说的是,首先尝试只拥有您的物品,并使用借来的引用来传递它。如果您确实需要共享,请查看 Rc
或 Arc
。如果还是不行,再考虑其他的。
同样,Rust Book 的描述非常好,您必须了解借用才能对使用什么有直觉。
What are the use cases for
Box
,Rc
,Ref
,RefMut
(others?) in Rust?
好的,我们开始:
Box
,用最简单的话来说,当你有一个对象你想保留在堆上时使用。什么时候用盒子- 您想own a dynamically sized object
- 您想将对象泄漏到
'static
lifetime - 您想制作一个 ffi pointer
- 您想recursive types
Rc
在很难决定对象的生命周期时使用。过度使用是懒惰的表现,在某种程度上违背了生命的目的。
例如,Ref
和RefMut
是由RefCell
when you try to get access to its contents. ARefCell
will track the borrowing state of its object at runtime instead of compile time, so it is kind of like lifetimes. A general use for this is when you need to have mutable references to many objects in a hashmap 生成的对象。Arc
is used with eitherRwLock
(Essentially the same asRefCell
apart from what's below) orMutex
尝试跨线程边界共享对象时。他们页面上的示例将向您展示如何使用它们以及为什么它们比使用Rc<RefCell<T>>
模式更重要。
rust 本身还有一些 "smart" 指针,但您必须知道,除非您使用不安全代码或直接使用全局分配器,否则所有内容最终都会取消分配其内容。
这与为什么语言中内置的工具(生命周期)对 Rust 如此重要有关,它们完成了 Rc
和 RefCell
完成的所有工作,但没有性能缺陷,并且还做了 C/C++
没有UB的机会。