我读了几篇文章,对我来说仍然不清楚。只要编译器不显示任何错误,它看起来T并且&T可以互换。但是在我阅读了官方文档后,我想通过引用传递所有内容以利用借用。
你能否提供关于传递一个ARG作为任何简单的规则T对&T当T是一个对象/字符串?例如,在 C++ 中有 3 个选项:
T – 复制值,不能改变当前值&T – 不创建副本,可以改变当前值const &T – 不创建副本,不能改变当前值例如,T如果我想在 T 在我的子函数(我要传递T给的函数)中超出范围后解除分配,那么传递它是个好主意吗?并使用&T如果我想在只读模式下使用我的子函数,然后继续在我当前的(父)函数中使用它。
谢谢!
这些是我个人使用的规则(按顺序)。
按值传递(T)如果该参数有一个通用的类型和性状,这种通用型器具都以&self或&mut self ,但有一条毯子impl的&T或&mut T所有类型(分别)T实现该特征(或这些特性)。例如,在 中std::io::Write,所有方法都采用&mut self,但impl<'a, W: Write + ?Sized> Write for &'a mut W标准库提供了一个全面的实现。这意味着尽管您接受 a T(where T: Write) 按值,但可以传递 a&mut T因为&mut T也实现了Write.
通过值(PASS T),如果你一定要把价值的所有权(例如,因为你把它传递给另一个函数/方法,通过价值需要它,或者因为选择则会要求潜在的昂贵克隆)。
通过可变引用传递(&mut T),如果你必须变异的对象(通过或只是通过覆盖调用其他功能/是采取通过可变引用的对象的方法和所需号码看到新的值),但不需要采取所有权其中。
T如果类型是Copy并且是小(我的小标准是size_of::<T>() <= size_of::<usize>() * 2,但其他人的标准可能略有不同),则通过值 ( )传递。原始整数和浮点类型就是此类类型的示例。通过引用传递这些类型的值会在内存中创建不必要的间接寻址,因此调用者必须执行额外的机器指令来读取它。当 时size_of::<T>() <= size_of::<usize>(),您通常不会通过引用传递值来保存任何内容,因为T和&T通常会在单个寄存器中传递(如果函数的参数很少)。
&T否则通过共享引用 ( )传递。
一般来说,尽可能通过共享引用传递。当类型很大或管理内存以外的资源时,这避免了潜在的昂贵的克隆,并在调用后如何使用值方面为调用者提供了最大的灵活性。
例如,
T如果我想T在它超出我的子函数(我传递T给的函数)的范围后解除分配,那么传递它是个好主意吗?
你最好有一个很好的理由!如果您决定实际上需要T在调用者中使用后者,那么您将不得不更改被调用者的签名并更新所有调用站点(因为与 C++ 不同,从T到const T&在大多数情况下是透明的,在 Rust 中从T到到&T不是:您必须&在所有调用站点的参数前添加一个)。
如果您还没有使用Clippy,我建议您使用它。Clippy 有一个 lint 可以通知您,如果您编写一个按值接受参数的函数,但该函数不需要取得它的所有权(此 lint 曾经默认发出警告,但现在不再发出警告,因此您必须使用#[warn(clippy::needless_pass_by_value)])手动启用它。
| 归档时间: |
|
| 查看次数: |
489 次 |
| 最近记录: |