V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
longkas239
V2EX  ›  Rust

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

  •  
  •   longkas239 · 2021-06-06 16:14:19 +08:00 · 2798 次点击
    这是一个创建于 1298 天前的主题,其中的信息可能已经有所发展或是发生改变。

    利用 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
    
    8 条回复    2021-06-06 18:12:09 +08:00
    shidenggui
        1
    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
        2
    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
        3
    longkas239  
    OP
       2021-06-06 16:55:50 +08:00
    @shidenggui @Jirajine 主要是想动态的组装一个字符串赋值过去, 所以不把数组中的类型换成 String 就没有办法这么做是吧。能把堆上存储的 String 复制到栈上变成&str 吗
    shidenggui
        4
    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
        5
    Jirajine  
       2021-06-06 17:05:17 +08:00
    @longkas239 #3 当然可以,像我写的那样不就是实现了动态组装一个字符串,然后把引用存到栈上么。并且你的 string literal 是存到静态资源里,也不是栈上,标准库里的 String 类型不能存到栈上,栈上只能存引用。

    当然如果你想避免堆分配,可以看一下 https://lib.rs/crates/inlinable_string
    12101111
        6
    12101111  
       2021-06-06 17:47:44 +08:00
    你的数组里存的是&'static str, 即只读的字符串, 你的 names 应该是 String 的数组
    VDimos
        7
    VDimos  
       2021-06-06 17:49:35 +08:00 via Android
    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
        8
    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(),
    }
    }
    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1835 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:27 · PVG 00:27 · LAX 08:27 · JFK 11:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.