用字符串数组折叠

Fold with string array

我试过这样的代码:

fn main() {
   let a = vec!["May", "June"];
   let s = a.iter().fold("", |s2, s3|
      s2 + s3
   );
   println!("{}", s == "MayJune");
}

结果:

error[E0369]: cannot add `&&str` to `&str`
 --> a.rs:4:10
  |
4 |       s2 + s3
  |       -- ^ -- &&str
  |       |  |
  |       |  `+` cannot be used to concatenate two `&str` strings
  |       &str
  |
help: `to_owned()` can be used to create an owned `String` from a string
reference. String concatenation appends the string on the right to the string
on the left and may require reallocation. This requires ownership of the string
on the left
  |
4 |       s2.to_owned() + s3
  |       ^^^^^^^^^^^^^

好的,很公平。所以我把我的代码改成了那样。但后来我明白了:

error[E0308]: mismatched types
 --> a.rs:4:7
  |
4 |       s2.to_owned() + s3
  |       ^^^^^^^^^^^^^^^^^^
  |       |
  |       expected `&str`, found struct `std::string::String`
  |       help: consider borrowing here: `&(s2.to_owned() + s3)`

好的,很公平。所以我把我的代码改成了那样。但后来我明白了:

error[E0515]: cannot return reference to temporary value
 --> a.rs:4:7
  |
4 |       &(s2.to_owned() + s3)
  |       ^--------------------
  |       ||
  |       |temporary value created here
  |       returns a reference to data owned by the current function

为什么 Rust 给出了虚假的建议,我正在尝试做的事情是否可行?请注意,我宁愿避免诸如“只使用 join”或类似的建议,因为这个问题旨在解决更普遍的问题。铁锈版本:

rustc 1.46.0 (04488afe3 2020-08-24)

is what I am trying to do possible?

Stargazeur 在他们的评论中提供了一个工作版本:初始值/累加器需要是 String 而不是 &str

Why is Rust giving bogus suggestion

Rustc 没有 global-enough 愿景,因此它能够看到“细节”问题,但它没有意识到这实际上是一个更大问题的局部影响:fold 的签名是

fn fold<B, F>(self, init: B, f: F) -> B 

因为您要给 fold 一个 &str,它最终必须 return 一个 &str,这只是如果 F 只是 return 它从“外部”获得的东西,而不是它在内部创建任何东西,则可能。由于您想在回调中创建一些东西,因此 init 的值就是问题所在。

Rustc 没有看到那个级别的冲突,因为就它而言,这是一个完全有效的签名,例如您可能正在通过 return 的哈希图跟踪一系列事物,并为其关心的所有内容设置一个常量字符串引用,它看到的唯一真正的冲突是:

 F: FnMut(B, Self::Item) -> B

你的函数的实现实际上不起作用,所以它试图帮助你:

  • Rust 不允许将两个 &str 相加,因为那样会隐式分配一个 String,这是核心团队不想隐藏的那种隐藏问题,所以 Add is only implemented between String and &str ,这是你看到的第一个问题,因为这有点不寻常(普通语言只允许你连接 string-ish 东西甚至 not-at-all-strings 到字符串)rustc 开发者添加了一个帮助文本,指出 LHS 必须是拥有的 String,通常有帮助/有效,但
  • 然后添加 return 一个 String,所以现在你的函数不再匹配 F 签名:因为 init 是一个 &str 类型累加器,所以你需要 return 一个 &str
  • 除非您尝试创建对刚刚创建的字符串的引用,否则您只是在函数内部创建它,一旦函数 returns 字符串将失效并且引用悬空,哪个铁锈不能允许

这就是尽管出于好意,但由于编译器的视图过于局限,它会无耻地将您引向一条完全无用的挫折之路。

您可能想在错误跟踪器上报告此问题(或查看它是否已经存在)。我不知道编译器诊断系统是否能够理解这种情况。