Display我正在尝试根据参数实现不同的格式。print_json()类似于和 的东西
print_pretty()。我当然可以将其实现为返回字符串的函数print_json(&self)->String,但我想知道是否可以使用print_json(&self,f: &mut Formatter<'_>) -> std::fmt::Resultandprint_pretty(&self,f: &mut Formatter<'_>) -> std::fmt::Result来代替。然后我可以根据用例调用其中一个函数。但如何Formatter直接获取实例呢?理想情况下我想做类似的事情
let mut string = String::new();
my_object.print_pretty(&mut string);
return string;
Run Code Online (Sandbox Code Playgroud)
\n\n但如何
\nFormatter直接获取实例呢?
据我所知,获取格式化程序的唯一方法是通过实现Display或其他格式化特征之一来接收格式化程序。
基于这个核心特征,我已经实现了自己的方案来添加更多格式选项:
\n/// Objects for which alternate textual representations can be generated.\n/// These are analogous to [`Display`] and [`Debug`], but have additional options.\npub trait CustomFormat<F: Copy> {\n /// Wrap this value so that when formatted with [`Debug`] or [`Display`] it uses\n /// the given custom format instead.\n fn custom_format(&self, format_type: F) -> CustomFormatWrapper<\'_, F, Self> {\n CustomFormatWrapper(format_type, self)\n }\n\n /// Implement this to provide custom formatting for this type.\n fn fmt(&self, fmt: &mut fmt::Formatter<\'_>, format_type: F) -> fmt::Result;\n}\nRun Code Online (Sandbox Code Playgroud)\n希望支持其他格式的类型实现CustomFormat<F>特定F格式类型或格式选项;对于您的用例,它们可能是struct Json;和struct Pretty;。或者,你可以有两个不同的特征 \xe2\x80\x94 我刚刚发现拥有一个通用的特征可以减少代码重复。
作为一个实现示例,我在这里定义了一个自定义格式std::time::Duration。它看起来就像DebugorDisplay实现,只是它需要一个额外的 format-options 参数(它会忽略该参数,因为StatusText它不带有任何额外的选项):
/// Objects for which alternate textual representations can be generated.\n/// These are analogous to [`Display`] and [`Debug`], but have additional options.\npub trait CustomFormat<F: Copy> {\n /// Wrap this value so that when formatted with [`Debug`] or [`Display`] it uses\n /// the given custom format instead.\n fn custom_format(&self, format_type: F) -> CustomFormatWrapper<\'_, F, Self> {\n CustomFormatWrapper(format_type, self)\n }\n\n /// Implement this to provide custom formatting for this type.\n fn fmt(&self, fmt: &mut fmt::Formatter<\'_>, format_type: F) -> fmt::Result;\n}\nRun Code Online (Sandbox Code Playgroud)\n使用这些工具的代码示例是:
\nimpl CustomFormat<StatusText> for Duration {\n fn fmt(&self, fmt: &mut fmt::Formatter<\'_>, _: StatusText) -> fmt::Result {\n write!(fmt, "{:5.2?} ms", (self.as_micros() as f32) / 1000.0)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n格式"{}"字符串不再控制格式;它只是一个占位符,用于调用格式机制,通过它CustomFormatWrapper实现Display(以及Debug)来调用自定义格式:
let mut string = String::new();\nwrite!(string, "{}", my_object.custom_format(Pretty)).unwrap();\nreturn string;\nRun Code Online (Sandbox Code Playgroud)\n对于您的目的来说,这可能是一个过度设计的解决方案。所需的关键元素是包装类型,其中包含对要格式化的值的引用,以及一些标准格式特征,例如Display转发到您的自定义格式特征(或者,如果您只想自定义格式一个)类型,只是该对象上的方法)。
| 归档时间: |
|
| 查看次数: |
1661 次 |
| 最近记录: |