这个问题是不是关于fn foo(x: &T)
和fn foo(ref x: T)
的区别。
我想问一下,使用后者在什么情况下是合适的/从习惯上讲是正确的。我无法想象在函数签名中需要ref
关键字的情况,因为您可以在函数中声明fn foo(x: T)
并使用&x
。
在函数参数列表的顶层,没有合理的ref
用例。它基本上导致值的所有权被移动到函数中,但您只得到一个引用来工作。
在函数参数列表中允许这样做的原因是与语言中其他部分的模式匹配语法保持一致。您可以使用任何不可辩驳的模式作为函数参数,就像在let
语句中一样。这些赋值的语法和语义本质上是相同的,但并不是技术上允许出现在函数参数列表中的所有内容都有意义,正如并非所有编译后的代码都是有用的一样。Clippy警告不要在函数参数列表的顶层使用ref
。
在函数参数表的解构中使用ref
可能是有用的。例如,如果您接受对一对&(String, String)
的引用,并且希望为这两个条目赋予单独的名称,则可以使用
fn foo(&(ref x, ref y): &(String, String))
来实现这一点。这里不使用ref
是无效的,因为你不能获得这些字符串的所有权。
由于match人机工程学的出现,ref
关键字的使用可以用更简洁的语法重写
fn foo((x, y): &(String, String))
我个人更喜欢更长的,更明确的版本,因为"人体工程学";version使x
和y
的类型更加不透明。