如何在Rust中处理字符串向量?解决E0515所有权编译错误
Rust反转单词时遇到所有权错误(E0515)
我正在通过编程挑战学习Rust,在JavaScript中实现反转单词的逻辑十分简单,但在Rust中遇到了问题。
JavaScript实现代码
// Decode the message by reversing the words function reverseWords(message) { return message.join("").split(" ").reverse().join(" ").split(""); }
我的Rust实现代码
// Decode the message by reversing the words fn reverse_words(message: Vec<&str>) -> Vec<&str> { let temp_a = message.join(""); let mut words: Vec<&str> = temp_a.split(" ").collect(); words.reverse(); let new_temp = words.join(" "); let result = new_temp.split("").collect(); result } #[cfg(test)] mod tests { use super::*; #[test] fn two_words() { let input = "thief cake".split("").collect(); let actual = reverse_words(input).join(""); let expected = "cake thief"; assert_eq!(actual, expected); } }
运行时错误信息
error[E0515]: cannot return value referencing local variable `new_temp` --> src/reverse_words/mod.rs:13:5 | 11 | let result = new_temp.split("").collect(); | ------------------ `new_temp` is borrowed here 12 | 13 | result | ^^^^^^ returns a value referencing data owned by the current function For more information about this error, try `rustc --explain E0515`.
问题根源
错误的核心是Rust的所有权与生命周期规则:new_temp是函数内部创建的局部String,调用split("")得到的&str都是指向new_temp的切片引用。当函数执行完毕后,new_temp会被销毁,这些引用就成了无效的悬垂引用——Rust会直接阻止这种不安全行为,因此抛出E0515错误。
修复方案
我们需要返回拥有所有权的数据类型,而不是引用。以下是两种可行的修复方式:
方案1:直接返回String(最简洁)
既然最终测试是要拼接成字符串比较,直接返回String更符合需求:
fn reverse_words(message: Vec<&str>) -> String { let full_message = message.join(""); full_message.split_whitespace() .rev() .collect::<Vec<_>>() .join(" ") } #[cfg(test)] mod tests { use super::*; #[test] fn two_words() { let input = "thief cake".split("").collect(); let actual = reverse_words(input); let expected = "cake thief"; assert_eq!(actual, expected); } }
方案2:返回字符集合Vec
如果必须保持返回字符级别的集合,返回Vec<char>替代Vec<&str>(避免引用问题):
fn reverse_words(message: Vec<&str>) -> Vec<char> { let full_message = message.join(""); let reversed_words = full_message.split_whitespace() .rev() .collect::<Vec<_>>() .join(" "); reversed_words.chars().collect() } #[cfg(test)] mod tests { use super::*; #[test] fn two_words() { let input = "thief cake".split("").collect(); let actual = reverse_words(input).into_iter().collect::<String>(); let expected = "cake thief"; assert_eq!(actual, expected); } }
额外提示
- 用
split_whitespace()替代split(" "),能自动处理多个连续空格的情况,逻辑更健壮; - Rust中无需像JS那样反复拆分/拼接字符数组,直接通过字符串和迭代器操作即可完成需求,减少不必要的中间步骤。
内容的提问来源于stack exchange,提问作者Freddy Rangel
相关产品推荐
相关产品推荐

