微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将 Vec<> 传播到 format!() 的参数中?

如何解决如何将 Vec<> 传播到 format!() 的参数中?

我有一个 Vec 字符串(strString),我想将它们用作 format!() 的参数。如果 JS 的 ... 语法可用,我会这样做:

let data = vec!["A","B","C"];
let result = format!("{} says hello to {} but not to {}",...data);

在 Rust 中是否有任何替代方案可以使这样的事情成为可能,并且理想情况下它不会变得非常冗长?

我认为部分困难在于 Vec 可能没有正确数量的参数,因此如果它有错误数量,我可以接受它恐慌。

解决方法

如果不手动编写大量代码或使用过程宏来生成必要的代码,目前没有办法做到这一点。

作为更简单的解决方法,您可以尝试使用 dynfmt,它提供了动态传递参数的方法。

use dynfmt::{Format,SimpleCurlyFormat};

let formatted = SimpleCurlyFormat.format("{} says hello to {} but not to {}",&["A","B","C"]);
assert_eq!("A says hello to B but not to C",formatted.expect("formatting failed"));
,

dyn-fmt crate 看起来正是我需要的。它指定了一个特征,它向字符串添加了一个 format() 方法,它接受一个迭代器。任何额外的参数都会被忽略,缺少的参数会被替换为一个空字符串,所以它不会恐慌。如果您不需要 format!() 的各种格式选项,那么它看起来是一个非常好的可靠选项。

use dyn_fmt::AsStrFormatExt;
let data = vec!["A","C"];
let result = "{} says hello to {} but not to {}".format(data);
assert_eq!(result,"A says hello to B but not to C");
,

我认为在@Netwave 的回答中生成 Vec<String> 是一种浪费,所以我使用 iter.flat_map() 对其进行了改进:

fn flat_map_niave(b: &mut Bencher) {
    let data = vec!["A","C"];
    let separators = vec![" says hello to "," but not to "];
    b.iter(|| {
        let mut phrases = separators.iter();
        data.iter()
            .intersperse_with(|| phrases.next().unwrap())
            .flat_map(|s| s.chars())
            .collect::<String>()
    });
}

有多种技巧可以以牺牲可读性为代价来提高性能,我将这些技巧留在 playground 中。

  • flat_map_improved:使用 Vec<u8>String::from_utf8()
  • flat_map_unchecked:使用 Vec<u8>String::from_utf8_unchecked()
running 4 tests
test flat_map_improved  ... bench:         134 ns/iter (+/- 17)
test flat_map_niave     ... bench:         145 ns/iter (+/- 9)
test flat_map_unchecked ... bench:         116 ns/iter (+/- 6)
test vec_of_strings     ... bench:         235 ns/iter (+/- 6)
,

您不能像在 jspython 中那样扩展它们。 但是您可以在 joinVec<String> 上使用 Vec<&str>

let data = vec!["A","C"];
let result = data.join("->");

Playground

根据 nightly,您可以使用 intersperse_with 和迭代器的组合:

    let data = vec!["A","C"];
    let phrases = vec![" says hello to "," but not to "];
    let mut separators = phrases.iter().map(|x| x.to_string());
    let result = data
        .iter()
        .map(|x| x.to_string())
        .intersperse_with(|| separators.next().unwrap())
        .collect::<String>();

Playground

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?