下面的示例显示了两个函数 foo()
和 bar()
,它们试图连接两个字符串。如果左侧的 +
参数是 &String
,则代码将无法编译。
这在 foo()
中得到了例证,它无法编译并显示错误消息 [E0369]。函数 bar()
表明我可以通过克隆 LHS 参数来摆脱这种情况。我的直觉表明这种克隆应该是多余的。
为什么我必须 clone()
LHS 参数?这是 Rust +
运算符当前实现状态的反射(reflect),还是背后有更深层次的思考?
// rustc 1.7.0-nightly (110df043b 2015-12-13)
fn foo(a: &String, i: i32) -> String {
a + &i.to_string() // .. '+' cannot be applied to type & .. String [E0369]
}
fn bar(a: &String, i: i32) -> String {
a.clone() + &i.to_string() // Ok
}
#[test]
fn my_test() {
assert!(foo(&"s".to_string(), 42) == "s42"); // fn foo(..) failed to compile
assert!(bar(&"s".to_string(), 42) == "s42"); // Ok
}
最佳答案
如果您查看 Add
的文档特征(或当前的 nightly docs for Add
),你会看到:
impl<'a> Add<&'a str> for String
这是 Add
的唯一实现对于 String
.此签名意味着它采用左侧按值,而不是按引用,因此需要调用 clone()
.
为了澄清,Add<&str>
对于 String
只是 String::push_str
的包装, 它附加到 String
的末尾,重新使用现有分配。通过不可变指针执行此操作不可能,通过可变指针执行此操作真的很奇怪并且有悖于合理的预期。因此,它要求 LHS 按值传递。
取决于你问的是谁,+
为 String
的任何形式定义的运算符是一个疣,所以是否定义额外的形式是......好吧,据我所知,这是一个悬而未决的问题。
关于operator-overloading - E0369 连接字符串引用时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34370277/