Rust初步(七):格式化

时间:2021-06-04 00:03:52

在Rust中,如果要进行屏幕输出,或者写入到文件中,需要对数据进行格式化。这一篇总结一下它所支持的几种格式化方式。

这篇文章参考了以下官方文档,不过,按照我的风格,我还是会突出于C#语言的比较,这样可能更好懂一些。

http://rustbyexample.com/hello/print.html

http://doc.rust-lang.org/std/fmt/

http://rustbyexample.com/hello/print/print_debug.html

http://rustbyexample.com/hello/print/print_display.html

首先,有三个常见的宏,可以用来做格式化

  • format!: write formatted text to String  这个宏可以将一个文本格式化成String类型(可变字符串,在堆上面分配空间),类似于C#中的String.Format方法。
  • print!: same as format! but the text is printed to the console.  和format!这个宏功能一样,只不过是输出到屏幕上。类似于C#中的Console.Write方法。
  • println!: same as print! but a newline is appended. 同上,只不过添加了换行符,类似于C#中的Console.WriteLine方法。

既然搞清楚了这三个宏,与C#中有关实现方式的关系,其实就很好理解了。一般这类方法,都可以比较方便地组合字符串,通过占位符这种东西。在C#中,用{0}表示第一个占位符,用{1}表示第二个占位符,依次类推。

https://msdn.microsoft.com/zh-cn/library/system.string.format(v=vs.110).aspx

https://msdn.microsoft.com/zh-cn/library/txafckwd(v=vs.110).aspx

但是Rust提供了一些自己的创新做法,它可以直接用空的占位符 {}(这个在C#中不允许的),也可以用带序号的占位符 {0},还直接带名称的占位符{name},同样,也支持在占位符里面指定特殊格式化的符号,例如{:?} 。 这里有一篇详细的介绍http://doc.rust-lang.org/std/fmt/

fn main() {
// In general, the `{}` will be automatically replaced with any
// arguments. These will be stringified.
println!("{} days", 31); // Without a suffix, 31 becomes an i32. You can change what type 31 is,
// with a suffix. // There are various optional patterns this works with. Positional
// arguments can be used.
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); // As can named arguments.
println!("{subject} {verb} {predicate}",
predicate="over the lazy dog",
subject="the quick brown fox",
verb="jumps"); // Special formatting can be specified after a `:`.
println!("{} of {:b} people know binary, the other half don't", 1, 2); // It will even check to make sure the correct number of arguments are
// used.
println!("My name is {0}, {1} {0}", "Bond");
// FIXME ^ Add the missing argument: "James" // Create a structure which contains an `i32`. Name it `Structure`.
struct Structure(i32); // However, custom types such as this structure require more complicated
// handling. This will not work.
println!("This struct `{}` won't print...", Structure(3));
// FIXME ^ Comment out this line.
}

知道了如何做格式化,下面要讨论一个问题:具体对象到底怎么实现自己的字符串表现形式的呢?其实,之前我已经略微介绍到了这个问题

Rust初步(四):在rust中处理时间

从上面的例子中,我们知道,要将一个对象作为一个字符串输出的话,就需要对其进行转换。我们在C#中就是要实现ToString方法,在Rust里面,分别有两个方法Debug和Display方法。如果是元类型(Primitive Type),当然是没有问题的,基本上都已经实现了。

  • fmt::Debug: Uses the {:?} marker. Format text for debugging purposes.  如果我们的占位符使用{:?},默认会调用对象的Debug方法,如果没有,则会报告错误
  • fmt::Display: Uses the {} marker. Format text in a more elegant, user friendly fashion.如果我们的占位符使用{},,默认会调用对象的Display方法,如果没有,则会报告错误

注意,除了这两种形式,还有其他一些格式化输出方式

  • unspecified -> Display
  • ? -> Debug
  • o –> Octal //8进制
  • x –> LowerHex //16进制
  • X -> UpperHex
  • p –> Pointer
  • b –> Binary //二进制
  • e -> LowerExp
  • E -> UpperExp

下面考虑一个例子,来加深理解

struct Point{ //自定义一个结构体
x:i32,
y:i32
} fn main() {
let p = Point{x:3,y:5};
println!("{}",p.x);//打印x,这会成功
println!("{:?}",p);//直接打印整个结构体,因为没有实现Debug,会失败
println!("{}",p);//直接打印整个结构体,因为没有实现Display,会失败
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

这个例子连编译都不会通过

Rust初步(七):格式化

那么,如何实现Debug和Display呢?

Debug相对来说很简单,只要声明一下即可

#[derive(Debug)]
struct Point{ //自定义一个结构体
x:i32,
y:i32
} fn main() {
let p = Point{x:3,y:5};
println!("{}",p.x);//打印x,这会成功
println!("{:?}",p);//直接打印整个结构体,因为已经实现Debug,会成功 }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

那么,它是怎样输出的呢?

Rust初步(七):格式化

实际上就很类似于C#中所有Object的默认实现(ToString)

相比而言,Display是需要手工来实现的,大致如下

use std::fmt;

#[derive(Debug)]
struct Point{ //自定义一个结构体
x:i32,
y:i32
} impl fmt::Display for Point{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "x为{},y为{}", self.x,self.y)
} } fn main() {
let p = Point{x:3,y:5};
println!("{}",p);//直接打印整个结构体,因为已经实现Debug,会成功 }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

输出结果如下

Rust初步(七):格式化

Rust初步(七):格式化的更多相关文章

  1. Rust初步(五):Rust与C#性能比较

    我学习Rust的目的并不是说期望用它来取代掉现有的开发平台或语言.相反,我认为当前绝大部分研发团队,都不可能只用一个平台或者一个语言. 当组织增长,他们越来越依赖大量的编程语言.不同的编程语言有不同的 ...

  2. Rust初步(六):在C#中使用Rust组件

    上一篇文章,我们通过实例比较了一下C#和Rust的性能表现,应该说在Release模式下面,Rust进行计算密集型的运算还是有些比较明显的优势的.那么,我们有没有可能,在C#中做一些快速应用开发,而一 ...

  3. Rust初步(四):在rust中处理时间

    这个看起来是一个很小的问题,我们如果是在.NET里面的话,很简单地可以直接使用System.DateTime.Now获取到当前时间,还可以进行各种不同的计算或者输出.但是这样一个问题,在rust里面, ...

  4. Rust初步(三):使用atom搭配racer进行rust编程

    在rust.cc社区中有一个关于rust编辑器的讨论(话说很多人要学一个新语言,都会立即考虑编辑器的问题,包括我在内),主要关注的是,智能提示(这个真的太重要了).大家讨论下来有几个选择 1. ecl ...

  5. Rust初步(二):使用Visual Studio Code编写Rust程序(猜猜看游戏)

    我是照着下面这篇帮助文档,完成了第一个完整的Rust程序: 猜猜看 游戏 http://kaisery.gitbooks.io/rust-book-chinese/content/content/3. ...

  6. Rust初步(一):介绍

    最近在研究Rust这个新的语言.那么Rust是什么呢? Rust是一个注重安全与速度的现代系统编程语言,通过在没有垃圾回收的情况下保证内存安全来实现它的目标,这使它成为一个在很多其它语言不适合的用例中 ...

  7. Rust这个新的语言

    Rust这个新的语言 Rust初步(七):格式化 摘要: 在Rust中,如果要进行屏幕输出,或者写入到文件中,需要对数据进行格式化.这一篇总结一下它所支持的几种格式化方式. 这篇文章参考了以下官方文档 ...

  8. (4)格式化输出(%用法和format用法以及区别)

    %s用法(%s的用法是写多少个,后面就要传多少个) format用法(基本语法是通过{}和:来代替%.format函数可以接受不限个参数,位置可以不按顺序) 形式一(顺序填坑{}) >>& ...

  9. php字符操作

    //一:定义字符串的方法 //1.双引号 //2.单引号 //3.heredoc语法结构 //heredoc语法定义字符串 $str=<<<TAG 我的武功终成武林盟主TAG;//注 ...

随机推荐

  1. iOS 开发技巧收藏贴 链接整理

    54个技巧 57个技巧 正则表达式

  2. 程序员谈学习:我为什么要学习Linux&quest;

    http://kb.cnblogs.com/page/196876/ 好长时间没好好写点东西了,前段时间由于项目的需要出差了一个多月,期间各种加班,每天晚上加班到十点,回到宾馆实现是没什么精力再写博客 ...

  3. Android ImageButton &vert; Button &vert; TextView 点击和触摸效果

    ImageButton------------------------------------------------> 一.Java  代码: 在drawable目录下添加新的xml文件 bu ...

  4. C&num; 利用TextBox的Text属性实现换行加字符 &quot&semi;&bsol;r&bsol;n&quot&semi;

    要让一个TextBox显示多行文本就得把它的Multiline属性设置为true,可是如果你是要把TextBox的Text属性设置多行文本时,换行符由两个字符组成:"\r\n". ...

  5. JD &period; 圆角矩形、权重层级、浮动撑开盒子及元素的默认间距、清除浮动、隐藏盒子、盒子的撑开与撑破、子盒子垂直居中&vert;不占位置

    ---恢复内容开始--- 圆角矩形 border-radius:50%  40%  30%  33px:   像素.百分比.小数( 0.5 ) 左上.右上.右下.左下 权重: 标签 1 : 类选择器 ...

  6. hdu2669与hdu1576(扩展欧几里德)

    模板: int Extend_Euclid(int a, int b, int &x, int &y){         if(b == 0){             x = 1; ...

  7. luogu4365 秘密袭击 &lpar;生成函数&plus;线段树合并&plus;拉格朗日插值&rpar;

    求所有可能联通块的第k大值的和,考虑枚举这个值: $ans=\sum\limits_{i=1}^{W}{i\sum\limits_{S}{[i是第K大]}}$ 设cnt[i]为连通块中值>=i的 ...

  8. C&num; &lbrack;Win32&rsqb; &lbrack;API&rsqb; WS&lowbar;TABSTOP 無效的解決辦法

    關鍵: IsDialogMessage function MSG msg; int bRet = 1; while (bRet != 0) { if (PeekMessageW(&msg, ( ...

  9. &lbrack;poj P1475&rsqb; Pushing Boxes

    [poj P1475] Pushing Boxes Time Limit: 2000MS   Memory Limit: 131072K   Special Judge Description Ima ...

  10. Linux网络编程学习&lpar;二&rpar; ----- 进程控制&lpar;第三章&rpar;

    1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...