如何在Rust中将&str转换为~str?

19

顺便说一下,这是针对当前的0.6 Rust trunk,不确定确切的提交版本。

假设我想要遍历一些字符串,并且我的闭包接受一个借用的字符串指针参数(&str)。我希望我的闭包将其参数添加到一个拥有的字符串向量 ~[~str] 中以返回。我对Rust的理解很弱,但我认为字符串是一种特殊情况,您不能使用*对它们进行解引用,对吗?如何将我的字符串从&str传递给需要一个~str参数的向量的push方法呢?

这里是一些无法编译的代码:

fn read_all_lines() -> ~[~str] {
    let mut result = ~[];
    let reader = io::stdin();
    let util = @reader as @io::ReaderUtil;
    for util.each_line |line| {
        result.push(line);
    }
    result
}

它无法编译,因为它推断出结果的类型为[&str],因为这是我推送到它上面的类型。更不用说它的生命周期将是错误的,因为我正在添加一个生命周期较短的变量。

我知道我可以使用ReaderUtil的read_line()方法,它返回一个~str。但这只是个例子。

那么,如何从借用的字符串中获取一个拥有的字符串?或者我完全误解了。


1
现在这已经不太相关了,因为Rust已经更新到1.X版本。(Rust 1.X使用的是String和&str,而非~str)因此,将其标记为Rust 1.0之前的版本会很有帮助。我的希望是可以相应地调整搜索引擎的相关性。 - David J.
我可能有些不恰当,但我已经投票关闭了这个问题,因为它不适用于当前的 Rust 语法,其中不包括 ~。 - Richard Neish
3个回答

11

你应该调用StrSlice特质的方法to_owned,例如:

fn read_all_lines() -> ~[~str] {
    let mut result = ~[];
    let reader = io::stdin();
    let util = @reader as @io::ReaderUtil;
    for util.each_line |line| {
        result.push(line.to_owned());
    }
    result
}

StrSlice特性文档在这里:

http://static.rust-lang.org/doc/core/str.html#trait-strslice


1
2013年的Rust与现代的Rust看起来非常不同。 - leo848

4
你不能这样做。
首先,从语义上讲是不行的:一个`~str`承诺同一时间只有一件事情拥有它。但是`&str`是借用的,那么你从哪里借来的地方会发生什么?它没有办法知道你试图窃取它唯一的引用,并且在这之下破坏调用者的数据是相当无礼的。
其次,从逻辑上讲也是不行的:`~`指针和`@`指针在完全不同的堆中分配,而`&`不知道哪个堆,所以它不能被转换为`~`并且仍然保证底层数据位于正确的位置。
因此,您可以使用`read_line`或复制,我... 不太确定该怎么做 :)
我确实想知道为什么API是这样的,因为`&`是指针中最受限制的。`~`在这里应该也能很好地工作;就好像迭代的字符串已经存在于其他地方并且需要被借用一样。

4
起初,我认为可以使用“复制行”从借用指向字符串的指针创建拥有指针,但这似乎只是复制了借用指针。
因此,我找到了“str::from_slice(s: &str) -> ~str”。这可能是你需要的。

我也尝试了“复制行”。他们提供了一种读取所有行的方法,但是它会给你一个借用指针,你不能复制它们,这让我感到很奇怪。似乎str::from_slice使用了不安全的原始字节复制。 - Ross
1
是的,它会复制字符串。这正是你需要创建拥有指针的内容。如果函数能够按预期工作,我认为底层是否有不安全的调用并不重要。无论如何,我们在最深层次上都进行了不安全操作。 - Dmitry Belyaev
@DmitryBelyaev 谢谢。我更感兴趣的是它是如何实现的,看看是否有推荐的方法来复制借用的字符串。 - Ross

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