首页 > 其他分享 >Rust的Display和ToString:将对象转换为字符串

Rust的Display和ToString:将对象转换为字符串

时间:2024-03-01 11:23:36浏览次数:21  
标签:self fmt ToString Rust Formatter Display fn

在写代码的时候,我们经常需要将对象输出到屏幕上,或者转换为字符串;在Python中,我们可以为类型定义魔法函数__str__printstr()都会调用它;在C++中,我们可以为对象重载ostream& operator<<(ostream& os)函数,使用ostringstreamfstreamcout的时候会调用它。

在Rust中该实现什么,想必大家都能回答上来:Display。不过,你可能不知道,Display的责任并不仅仅局限于“显示”,还包括对象到字符串的转换;最有说服力的论据就是实现了Display之后,就会自动获得ToString的实现,这一点我们稍后会详细说明。

Display

Display特征的签名比之前我们介绍过的特征要更复杂:

pub trait Display {
    // Required method
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>;
}

Formatter是一个用于获取Display上下文信息的结构体,并且我们的输出结果也应该写到这个Formatter中;另外,虽然这个方法返回的是一个Result,但这不等于转换过程可以失败。Rust文档中这样描述这个“Result”:

与函数签名所暗示的相反,字符串格式化是一个不会失败的操作。这个函数只是因为写入底层流可能会失败,并且它必须提供一种方式来传递错误发生的事实回到调用栈上,所以才会返回一个Result

这是Rust文档上的一个案例:

use std::fmt;

#[derive(Debug)]
struct Vector2D {
    x: isize,
    y: isize,
}

impl fmt::Display for Vector2D {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}

Formatter

前面提到,Formatter充当了Rust和程序员之间的桥梁:我们通过Formatter来了解用户传入了哪些显示参数(例如对齐方向、填充字符、有/无符号等),并将生成好的结果写入Formatter内。除了Displayfmt模块中的其他用于格式化的特性也会使用Formatter

以下是Formatter中用于获取用户传入参数的一些方法:

// 获取用户请求的对齐方式
fn align(&self) -> Option<Alignment>;

// 获取用户请求的输出宽度
fn width(&self) -> Option<usize>;

// 获取填充字符
fn fill(&self) -> char;

// 获取用户请求的输出精度
fn precision(&self) -> Option<usize>;

// 获取是否提供了“+”标志
fn sign_plus(&self) -> bool;

// 获取是否提供了“-”标志
fn sign_minus(&self) -> bool;

// 获取是否提供了“#”标志
fn alternate(&self) -> bool;

Formatter也提供了一些用于输出的方法:

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>;

fn write_str(&mut self, data: &str) -> Result<(), Error>;

Formatter实现了Write特征。这也就是说我们可以直接使用write!()这样的宏来向Formatter写入内容,就像上方的案例一样。

应该实现Display吗?

我们知道,除Display外Rust中还有一个类似的特征:DebugDebug特征大伙都很熟悉,那什么时候该实现Display,什么时候该实现Debug呢?

  • Display要求类型在任何时候都能够被可靠地表示为字符串;它并没有被硬性要求。
  • Debug所有公共类型都应当实现的,并且一般来说不需要手动实现,而是应当使用#[derive(Debug)]Debug的输出通常会尽可能可靠地展示类型的内部状态。

ToString

ToString特征来自std::string模块,用于将一个值转换为String

pub trait ToString {
    // Required method
    fn to_string(&self) -> String;
}

ToString一眼望去和Display风马牛不相及,但是它却有一个重要的特点:只要类型实现了Display,那它就自动实现了ToString

在实践中,如果我们需要把数字转换为字符串的话,可以直接使用to_string()来便捷转换。

如果性能需求特别高的话,则应该考虑使用三方库itoaryu

但是,如果需要将&str转换为String的话,就应该用to_owned()而不是to_string()了;to_string()中构造Formatter的过程会造成性能浪费。这里我要批评一款Rust IDE,它总是为String类型的变量提供"".to_string()的默认值,在我年少懵懂的时候带来过不小的误导:


总结:这篇文章介绍了DisplayToString,虽然没有提及其他std::fmt中的格式化特性,但它们和Display是基本相通的,除了功能并无太大区别;此外,我也没有介绍format!()之类的宏的用法,因为那是Rust新手教程该做的事。下篇文章将会聚焦std::cell中的几个类型:CellRefCellOnceCell

标签:self,fmt,ToString,Rust,Formatter,Display,fn
From: https://www.cnblogs.com/cinea/p/18046576

相关文章

  • 为什么会有幽灵空白元素,display:inline/inline-block会出现空隙的原因
    display:inline-block样式会在一些情况下产生间隙,这通常是由于元素之间的空白符或换行符所致。具体来说,以下情况可能导致display:inline-block元素之间出现间隙:HTML源代码中的换行符和空格:如果display:inline-block元素之间有换行符或空格,浏览器会将这些空白符解释为......
  • Rust的From和Into特征:可能是最常用的转换类特征
    说到From和Into,以及从他们中衍生出的TryFrom和TryInto,想必大家都不会陌生。它们不像Borrow、AsRef、ToOwned这些默默工作在泛型里的特征,是绝大多数Rust开发者每天都会使用到的东西。今天我们就来加深一下对这四个特征的了解吧~From和Into如果说AsRef和AsMut的功能是做“引用到引......
  • Rust 交叉编译 macOS 为 Linux 和 Windows
    目录前言环境案例macOS编译为Linux和Windows可用二进制程序编译为Linux平台编译为Windows平台最后前言鉴于rust中文资料较少,遇到问题的解决方案更少。这里记录遇到的一些问题。Rust支持交叉编译,可以在macOS平台编译出Linux或者Windows可运行的程序,或者在Lin......
  • display: none与visibility: hidden的区别
    display:none首先我们来看W3C中对display:none的描述:'none'​The element anditsdescendantsgenerateno boxes or textsequences.​Similarly,ifa textnode isdefinedtobehaveas display:none,itgeneratesno textsequences.Elementswitheit......
  • 抖音技术分享:飞鸽IM桌面端基于Rust语言进行重构的技术选型和实践总结
    本文由ELab团队公众号授权发布,原题《Rust语言在IM客户端的实践》,来自抖音电商前端团队的分享,本文有修订和改动。1、引言本文将介绍飞鸽IM前端团队如何结合Rust对飞鸽客户端接待能力进行的技术提升,一步步从概念验证、路径分解到分工开发,再到最后上线收益论证,并分享了其中遇到的......
  • rust与python/c++语法区别
    if/matchpubfnanimal_habitat(animal:&str)->&'staticstr{letid=ifanimal=="crab"{//id等于(或拥有)了一个匿名函数的返回值1}elseifanimal=="gopher"{2}elseifanimal=="snake"......
  • 【rust】《 Rust安装并配置cargo国内源(提供rust编译器) 》
    下载Rust安装程序官网地址:https://www.rust-lang.org/tools/installWindow直接点击DownloadRustup-init.exe就可以下载运行程序。运行安装程序双击下载的rustup-init.exe程序,此时会弹出命令窗口命令窗口内输入1  ;1表示默认形式安装,Rust的环境变量会自动添加到系统......
  • Rust的Cow类型有什么用?详解Cow及其用途
    Rust的智能指针有哪些?大多数人都能马上答出Box<T>、Rc<T>和Arc<T>、Ref<T>和在异步编程中很常见的Pin<P>等等。不过,有一个可能经常被大多数人遗忘的类型,它功能强大,利用好了可以节省很多复制开销;它就是这篇文章的主角:Cow<B>。什么是COW(Copy-On-Write)?在开始之前,有必要先介绍一下CO......
  • Rust的ToOwned特征:泛型版的Clone
    std::borrow::ToOwned是Rust标准库中的一个特征,用于从借用的数据中创建一个具有所有权的副本。它的作用和Clone是一样的,但是相比Clone,它支持泛型;也就是说我们可以将一个类型T“Clone”为另一个类型U。这对处理一些特殊的类型来说很有用。ToOwned的签名ToOwned提供了两个方法,其中......
  • Rust的Deref特征:让智能指针“透明”的关键
    除了上篇文章中介绍过的Borrow和AsRef外,Rust中还有一个很常见的和引用相关的特征:Deref。不过,和Borrow、AsRef两个特征不同,Deref其实是用于重载解引用运算符(也就是*)的特征;在为某个类实现了Deref特征后,对它使用*运算就会调用特征中重载的方法。这篇文章不仅将介绍Deref特性,还将探......