如何从函数中返回一个反转的字符串?

3

我想要编写一个函数,可以将一个字符串反转并返回该字符串的引用。我认为我应该能够指定返回的引用与提供的引用具有相同的生命周期。

fn reverse_string<'a>(input: &'a str) -> &'a str {
    let res: &'a str = input.chars().rev().collect().as_slice();
    res
}

这是我的尝试,但我收到了错误提示:
error[E0282]: type annotations needed
 --> src/lib.rs:2:24
  |
2 |     let res: &'a str = input.chars().rev().collect().as_slice();
  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `B`
  |
  = note: type must be known at this point

我原本认为类型规范可以解决这个问题。生命周期对我来说有点困惑,所以我希望有人能够解释如何正确地处理这个问题,或者如果我一开始就完全错误的话。

2个回答

7
生命周期问题与 &str的生命周期使比较困难类似:如果您创建一个对象,它将成为一个新对象,并且与旧对象不相关。
因此,您有两个选择:
  • 要么创建一个全新的对象:input.chars().rev().collect() 例如
  • 要么就地反转input,这当然需要它是mut
前者看起来容易:
fn reverse_new(input: &str) -> String {
    input.chars().rev().collect()
}

然而,所创建的String可能存在缺陷,因为char(中间类型)只是Unicode代码点而不是字形。作为组合字符的一个示例,想象一下在原始字符串中有[e, ́, o],́附加到eéo,但是在反转后,你会得到[o, ́, e],其中́附加到oóe
后者的复杂性在于即使忽略字形问题,在原地反转UTF-8也需要了解UTF-8以避免拆分码点。当然,可以简单地创建一个反转的String并将其复制到输入中... 编辑:我最初考虑收集到一个中间的Vec中,但@AlexP意识到这是不必要的,可以直接收集到String中。

感谢您的帮助!然而,在尝试使用rust 0.12.0-dev编译上述代码片段时,我收到了错误信息:“在此上下文中需要知道该值的类型”,其中指出了“v.as_slice()”这部分。 - Alex P
我想知道返回的引用的生命周期是多久?我不确定关于借用方面返回引用的工作原理,也在文档中找不到任何信息。 - Alex P
谢谢@FrancisGagné,非常感谢您的帮助。 :) 我成功解决了我的问题。 - Alex P
@AlexP:你需要为 collect 添加注释吗?如果需要,你可以使用 let v: Vec<char> = ...; 或者 collect::<Vec<char>>(). - Matthieu M.
@AlexP:啊,很好,比使用临时向量还要好!唯一的缺陷,正如我所提到的,是Unicode包含组合字符。因此,如果您在原始字符串中有e后跟 ́后跟o,则 ́将附加到eéo,但在反转后,它将附加到oóe - Matthieu M.
显示剩余2条评论

0

最终按预期运行的函数:

fn reverse_string(input: &str) -> String {
    input.chars().rev().collect()
}

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