这个 Rust 例子里面怎么对字符串赋值

2021-06-06 16:14:19 +08:00
 longkas239

利用 match 循环匹配数组中的值,如果是 Apple,改成 RedApple:

let mut names = ["Apple", "Banana"];
for name in names.iter_mut() {
	*name = match name {
    	&mut "Apple" => { format!("Red{}", name).as_str() }
        _ => "Hello"
    }
}

报错:

&mut "Apple" => { format!("Red{}", name).as_str() }
- temporary value is freed at the end of this statement
    | |                               |
    | |                               creates a temporary which is freed while still in use
    _________- borrow later used here
    |
    = note: consider using a `let` binding to create a longer lived value
2544 次点击
所在节点    Rust
8 条回复
shidenggui
2021-06-06 16:38:03 +08:00
let mut names: Vec<String> = ["Apple", "Banana"].iter().map(|s| s.to_string()).collect();
for name in names.iter_mut() {
*name = match name.as_str() {
"Apple" => { format!("Red{}", name) }
_ => "Hello".to_string()
}
}
Jirajine
2021-06-06 16:45:35 +08:00
因为你这个数组里面存的是&str,也就是指向字符串的指针。你要把它改成别的,就得让它指向其他的字符串。而你代码里只创建了个临时的字符串,没有绑定到变量。
```rust
let mut names = ["Apple", "Banana"];
let red_apple = format!("Red{}", name);
for name in names.iter_mut() {
*name = match name {
&mut "Apple" => { red_apple.as_str() }
_ => "Hello"
}
}

```
longkas239
2021-06-06 16:55:50 +08:00
@shidenggui @Jirajine 主要是想动态的组装一个字符串赋值过去, 所以不把数组中的类型换成 String 就没有办法这么做是吧。能把堆上存储的 String 复制到栈上变成&str 吗
shidenggui
2021-06-06 16:58:41 +08:00
@longkas239 可以啊,只要你能接受对应的字符串内存泄漏就行

let mut names = ["Apple", "Banana"];
for name in names.iter_mut() {
*name = match name {
&mut "Apple" => { Box::leak(Box::new(format!("Red{}", name)) )}
_ => "Hello"
}
}
Jirajine
2021-06-06 17:05:17 +08:00
@longkas239 #3 当然可以,像我写的那样不就是实现了动态组装一个字符串,然后把引用存到栈上么。并且你的 string literal 是存到静态资源里,也不是栈上,标准库里的 String 类型不能存到栈上,栈上只能存引用。

当然如果你想避免堆分配,可以看一下 https://lib.rs/crates/inlinable_string
12101111
2021-06-06 17:47:44 +08:00
你的数组里存的是&'static str, 即只读的字符串, 你的 names 应该是 String 的数组
VDimos
2021-06-06 17:49:35 +08:00
names 是在栈里面的,你 format 的变量离开作用域就释放了,得用一些手段避开这些操作。
fn main() {
let mut names = ["A", "B"];
for name in names.iter_mut() {
*name = match name {
&mut "A" => {
let a = format!("GGG{}", name);
let r = unsafe {
let p = a.as_str() as *const str;
let s = &*p as &str;
s
};
std::mem::forget(a);
r
},
_ => "hello"
}
}

println!("{:#?}", names);
}
PeterD
2021-06-06 18:12:09 +08:00
names 是 [&'static str]。format!("Red{}", name) 不是 'static

```rust
pub fn main() {
let mut names = ["Apple".to_string(), "Banana".to_string()];
for name in names.iter_mut() {
match name.as_str() {
"Apple" => *name = format!("Red{}", name),
_ => *name = "Hello".to_string(),
}
}
}
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/781706

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX