当缓冲区大小不足时,write!似乎不写参数.

use std::fmt::Write;
use arrayvec::ArrayString; // 'arrayvec' crate

fn main() {
    const SIZE: usize = 16;
    let mut s = ArrayString::<SIZE>::new();
    match write!(s, "{}{}", "0123456789", "0123456789") {
        Ok(_) => println!("success!"),
        Err(err) => println!("{}", err),
    }
    println!("{}", s);
}

输出:

an error occurred when formatting an argument
0123456789

但是,我希望尽可能长地编写格式化字符串,直到缓冲区大小.在上面的例子中,我想要的输出是0123456789012345.

在C语言中,我们可以使用snprintf来实现这一点.

#include <stdio.h>
#include <stdlib.h>

int main() {
    char buf[16];
    snprintf(buf, 16, "%s%s", "0123456789", "0123456789");
    printf("%s\n", buf); // output is "012345678901234", due to '\0'
}

我怎么能在 rust 迹斑斑的地方做到这一点?

推荐答案

你可以为这个特性编写自己的适配器.比如:

struct FixedWriter<'a, W>(&'a mut W);

impl<'a, W: Write> Write for FixedWriter<'a, W> {
    fn write_str(&mut self, s: &str) -> Result<(), std::fmt::Error> {
        for c in s.chars() {
            self.0.write_char(c)?;
        }
        Ok(())
    } 
}

要使用它,只需包装原始作者的可变引用:

write!(FixedWriter(&mut s), "{}{}", "0123456789", "0123456789");

你可以判断这个playground,打印0123456789012345.

您还可以通过将?运算符替换为以下运算符来模拟成功:

if self.0.write_char(c).is_err() {
    break;
}

,但问题不清楚你是否需要这个.

Rust相关问答推荐

如何在rust中有条件地分配变量?

如何在不安全的代码中初始化枚举 struct

如何提高自定义迭代器的`extend`性能

捕获FnMut闭包的时间不够长

如何在Rust中将选项<;选项<;字符串>;转换为选项<;选项&;str>;?

为什么&;mut buf[0..buf.len()]会触发一个可变/不可变的borrow 错误?

Rust将String上的迭代器转换为&;[&;str]

如何初始化选项<;T>;数组Rust 了?

不同类型泛型的映射

用于实现获取 struct 体 id 的特征规范

方法可以被误认为是标准特性方法

pyO3 和 Panics

使用 lalrpop 在 rust 中解析由 " 引用的字符串

没有得到无法返回引用局部变量`queues`的值返回引用当前函数拥有的数据的值的重复逻辑

如何判断服务器是否正确接收数据

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

为什么我可以同时传递可变和不可变引用?

如何在 Rust Polars 中可靠地连接 LazyFrames

为实现特征的所有类型实现显示

为什么分配对变量的引用使我无法返回它