为什么编译器阻止我在使用 collect() 创建的 Vec 上使用 push? [英] Why does the compiler prevent me from using push on a Vec created using collect()?

查看:61
本文介绍了为什么编译器阻止我在使用 collect() 创建的 Vec 上使用 push?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下编译:

pub fn build_proverb(list: &[&str]) -> String {
    if list.is_empty() {
        return String::new();
    }
    let mut result = (0..list.len() - 1)
        .map(|i| format!("For want of a {} the {} was lost.", list[i], list[i + 1]))
        .collect::<Vec<String>>();
    result.push(format!("And all for the want of a {}.", list[0]));
    result.join("\n")
}

以下没有(见游乐场):

pub fn build_proverb(list: &[&str]) -> String {
    if list.is_empty() {
        return String::new();
    }
    let mut result = (0..list.len() - 1)
        .map(|i| format!("For want of a {} the {} was lost.", list[i], list[i + 1]))
        .collect::<Vec<String>>()
        .push(format!("And all for the want of a {}.", list[0]))
        .join("\n");
    result
}

编译器告诉我

error[E0599]: no method named `join` found for type `()` in the current scope
 --> src/lib.rs:9:10
  |
9 |         .join("\n");
  |          ^^^^

如果我尝试仅使用 push 进行组合,我会遇到相同类型的错误.

I get the same type of error if I try to compose just with push.

我期望的是 collect 返回 B,也就是 Vec.Vec 不是 ()Vec 当然有我想包含在组合函数列表中的方法.

What I would expect is that collect returns B, aka Vec<String>. Vec is not (), and Vec of course has the methods I want to include in the list of composed functions.

为什么我不能组合这些函数?解释可能包括描述在 collect() 之后终止表达式的魔法",以使编译器以一种在我编写时不会发生的方式实例化 Vecpush

Why can't I compose these functions? The explanation might include describing the "magic" of terminating the expression after collect() to get the compiler to instantiate the Vec in a way that does not happen when I compose with push etc.

推荐答案

如果您阅读了 Vec::push 的文档并查看该方法的签名,您将了解到它不返回 Vec:

pub fn push(&mut self, value: T)

由于没有明确的返回类型,返回类型是单位类型 ().() 上没有名为 join 的方法.您需要在多行中编写代码.

Since there is no explicit return type, the return type is the unit type (). There is no method called join on (). You will need to write your code in multiple lines.

另见:

我会更实用地写这个:

use itertools::Itertools; // 0.8.0

pub fn build_proverb(list: &[&str]) -> String {
    let last = list
        .get(0)
        .map(|d| format!("And all for the want of a {}.", d));

    list.windows(2)
        .map(|d| format!("For want of a {} the {} was lost.", d[0], d[1]))
        .chain(last)
        .join("\n")
}

fn main() {
    println!("{}", build_proverb(&["nail", "shoe"]));
}

另见:

这篇关于为什么编译器阻止我在使用 collect() 创建的 Vec 上使用 push?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆