拆分字符串并返回碎片

时间:2014-12-18 04:10:53

标签: string rust

如何在函数内部创建一个String,拆分它并返回其内容?下面的代码失败,因为变量s的生命周期在函数f的末尾结束,但返回的Obj超出了此范围。我希望将holder移动到Obj会将其生命周期与'a联系起来,但这似乎不起作用。还有另一种方法可以实现这个目标吗?

struct Obj<'a> {
    holder : String,
    p1 : &'a str,
    p2 : &'a str,
    p3 : &'a str
}

fn f<'a>() -> Obj<'a> {
    //let slice = "a,b,c";
    let s : String = from_str("a,b,c").unwrap();
    let slice = s.as_slice();
    let pieces : Vec<&'a str> = slice.split_str(",").collect();

    Obj {
        holder : s,
        p1: pieces[0],
        p2: pieces[1],
        p3: pieces[2]
    }
}

fn main() {
    let obj = f();
    println!("{}", obj.p2);
}

2 个答案:

答案 0 :(得分:1)

当你从某个函数返回某个东西时,你不能“延长”它的生命周期;你只是不能

但是,有几种方法可以重写这段代码:

  1. Obj懒洋洋地计算这些碎片。也就是说,你返回一个Obj,它有一个方法与f做同样的事情。这样,您可以将片段的生命周期与&self的生命周期联系起来(这将是Obj实例)。在这种情况下,Obj将不需要'a参数。

  2. 使每个部分成为拥有其内容的新分配的String(从而避免生命周期问题)。然后,它变为f() -> (String, String, String)

  3. s为参数,允许您将各个部分的生命周期与 联系起来。在这种情况下,您最终会得到f(s: &str) -> (&str, &str, &str)

  4. 通常,您不能在函数内部创建某些内容,然后返回对它的引用。

答案 1 :(得分:0)

您不能拥有包含引用同一struct的其他成员的借用指针的struct。这有两个选项可以解决这个问题:

  • 存储每个子字符串的开头和长度,或每个子字符串的开头和结尾。您可以在结构上提供方法以按需构造切片。
  • 存储String s(使用into_string转换切片)。您不需要使用此解决方案存储原始字符串,但它会在堆上分配更多内存。
相关问题