Rust无法返回引用局部变量的值。

4

我猜这是一个相当基础的Rust问题,但是我有一段这样的代码:

struct Stock<'a> {
    name: &'a str,
    value: u8,
}
impl<'a> Stock<'a> {
    fn read(file: &mut File) -> Stock<'a> {
        let mut value = vec![0; 1];
        file.read(&mut value);
        let name_size = read_u32(file);
        let mut name = vec![0; name_size as usize];
        file.read(&mut name);
        return Stock {
            name: str::from_utf8(&name).unwrap(),
            value: value[0],
        };
    }
}

当然,它不起作用,因为我引用了一个本地值名称。据我所知,这是因为在read的范围之外,name不存在。但是,from_utf8会不会创建一个不受read限制的新变量呢?
此外,我读到一些其他人遇到这个问题的情况,并且建议总是切换到拥有的String。但是,为什么我不能做这样的事情: name: str::from_utf8(&name).unwrap().to_owned()

1
以下是如何使用 String(以及其他一些改进)的示例:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e31965f9a799dc5aca26360538cf630f - trent
回复:但是为什么我不能这样做,比如 name: str::from_utf8(&name).unwrap().to_owned() 是的,这会给你一个String。我不确定我理解这里的反对意见。只需使用String即可。 - trent
我的问题是我还没有完全理解这种语言,也没有完全理解to_owned会给我一个String :) 但是,你的回答确实帮了我很多(特别是代码示例)。我只需要完全理解它们。 - munHunger
2个回答

2
然而,from_utf8 不会创建一个新的变量,它返回的是与传入参数相同生命周期的借用。即使它创建了一个新的变量,你也需要将其绑定到某个地方,例如 read() 的作用域,所以你仍然会遇到同样的问题。问题在于你的 Stock 结构体包含一个引用。这意味着它指向的任何内容都必须在 Stock 存活期间一直存在。但是,在 read() 的局部作用域中创建的任何变量都会在 read() 结束时销毁。相反,你需要让 Stock 拥有该值,以便它自己保持其生命。

0
你最好将结构体字段改为name: String,并且去掉'a生命周期参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接