gpt4 book ai didi

rust - 如何在没有多次分配的情况下实现条件嵌套格式?

转载 作者:行者123 更新时间:2023-12-05 01:22:33 25 4
gpt4 key购买 nike

我有一个由多个条件组件组成的格式字符串,我正在寻找一种不需要为中间步骤分配多个字符串的解决方案。如果我使用 format!-macro 创建最终格式字符串的每个单独组件,那么它可以工作,但我需要为每个组件分配一个。

我尝试只使用宏来生成复杂的格式字符串及其参数。但是,这总是导致“临时值在该语句末尾被释放”错误。我尝试使用一个 impl core::fmt::Write 类型的缓冲区,但我也无法成功。

在高层次上,我想要这样的东西:

fn main() {
let prefix_include_a = true;
let prefix_include_b = true;
// prefix itself is a formatted string and it is further formatted here
println!("{prefix:<10}{message:>10}!",
prefix = format_prefix(prefix_include_a, prefix_include_b),
message = "message"
);
}

// formats the prefix component of the final string.
// needs multiple String allocations as `format!` is used
fn format_prefix(inc_a: bool, inc_b: bool) -> String {
format!("[{a:<5}{b:<5}]",
a = if inc_a {
format!("{:.1}", 1.234)
} else {
format!("")
},
b = if inc_b {
format!("{:.2}", 1.234)
} else {
format!("")
},
)
}

这是否可能没有或只有一个分配?

最佳答案

最简单的解决方案是直接write! 到底层流,例如

use std::io::{stdout, Write};

fn main() {
let prefix_include_a = true;
let prefix_include_b = true;

let mut stdout = stdout();
let _ = format_prefix(&mut stdout, prefix_include_a, prefix_include_b);
let _ = write!(stdout, "{:>10}", "message");
}

// formats the prefix component of the final string.
// needs multiple String allocations as `format!` is used
fn format_prefix(mut s: impl Write, inc_a: bool, inc_b: bool) -> std::io::Result<()> {
write!(s, "[")?;
if inc_a {
write!(s, "{:<5.1}", 1.234)?;
} else {
write!(s, " ")?;
}
if inc_b {
write!(s, "{:<5.2}", 1.234)?;
} else {
write!(s, " ")?;
}
write!(s, "]")?;
Ok(())
}

另一种方法是将prefix具体化为一个类型,并为其实现Display。我会认为(希望?)格式化程序是底层流的直通,尽管我从未真正看过:

use std::io::{stdout, Write};

fn main() {
let prefix_include_a = true;
let prefix_include_b = true;

println!(
"{prefix:<10}{message:>10}!",
prefix = Prefix(prefix_include_a, prefix_include_b),
message = "message"
);
}

struct Prefix(bool, bool);
impl std::fmt::Display for Prefix {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[")?;
if self.0 {
write!(f, "{:<5.1}", 1.234)?;
} else {
write!(f, " ")?;
}
if self.1 {
write!(f, "{:<5.2}", 1.234)?;
} else {
write!(f, " ")?;
}
write!(f, "]")?;
Ok(())
}
}

注意:我没有在任何一个版本中处理前缀的填充,但我认为这没有多大意义:两个前缀值都被填充为 5,因此前缀始终至少为 12 宽。填充到 10 是没有意义的。

但是,如果需要,前缀对象可以使用外部指定的填充来分发到内部填充。参见 std::fmt::Formatter获取有关格式说明符的信息。

要清理条件,您可能会使用 format_args! ,尽管我对此经验不多。

关于rust - 如何在没有多次分配的情况下实现条件嵌套格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73715786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com