Rust字符串拼接与借用机制疑问:为何两种String加法写法运行结果不同
核心原因:Rust的
String拼接是定向实现的非对称运算符重载 - 和多数语言中字符串
+运算符的对称匹配逻辑不同,Rust标准库针对String类型的Add(也就是+运算符)的公开实现是定向、非对称的,其固定签名为impl Add<&str> for String,匹配规则十分明确:- 运算符左侧必须是持有完整所有权的
String实例,左值会通过值传递的方式被移动到拼接逻辑中,直接复用其内存空间做扩容,不需要额外拷贝左值的字符串内容,最大化拼接性能 - 运算符右侧必须是可以自动强转为
&str的引用类型,比如第一个可运行代码中的&s2(&String)可以通过 Deref 特性自动转换为&str,完全符合右值的类型要求,因此可以正常编译运行
- 运算符左侧必须是持有完整所有权的
- 调整后的写法
let s3 = &s1 + s2;同时违反了两条运算符匹配规则,因此无法通过编译:- 左侧操作数
&s1是&String类型,标准库从未给&String实现过Add运算符,编译器根本找不到能匹配这个左值的重载逻辑 - 右侧操作数
s2是持有所有权的String类型,也不符合“右值需要是&str类引用”的要求,两个操作数的类型和重载的参数要求完全错配
- 左侧操作数
- 补充说明:第一个写法中
s1 + &s2执行完成后,后续代码不能再直接访问s1,是因为左值的所有权已经被移动到拼接逻辑中,属于Rust所有权机制的正常表现,并非代码异常。如果需要灵活拼接任意类型的字符串,更推荐使用format!宏,不需要严格匹配+运算符的左右值类型要求,可读性更好。
内容的提问来源于stack exchange,提问作者Sanskar Jethi
相关产品推荐
相关产品推荐

