关于打印的更多信息

在Rust中,你几乎可以用任何你想要的方式打印东西。这里有一些关于打印的事情需要知道。

添加 \n 将会产生一个新行,而 \t 将会产生一个标签。

fn main() {
    // Note: this is print!, not println!
    print!("\t Start with a tab\nand move to a new line");
}

这样就可以打印了。

         Start with a tab
and move to a new line

""里面可以写过很多行都没有问题,但是要注意间距。

fn main() {
    // Note: After the first line you have to start on the far left.
    // If you write directly under println!, it will add the spaces
    println!("Inside quotes
you can write over
many lines
and it will print just fine.");

    println!("If you forget to write
    on the left side, the spaces
    will be added when you print.");
}

这个打印出来的。

Inside quotes
you can write over
many lines
and it will print just fine.
If you forget to write
    on the left side, the spaces
    will be added when you print.

如果你想打印\n这样的字符(称为 "转义字符"),你可以多加一个\

fn main() {
    println!("Here are two escape characters: \\n and \\t");
}

这样就可以打印了。

Here are two escape characters: \n and \t

有时你有太多的 " 和转义字符,并希望 Rust 忽略所有的字符。要做到这一点,您可以在开头添加 r#,在结尾添加 #

fn main() {
    println!("He said, \"You can find the file at c:\\files\\my_documents\\file.txt.\" Then I found the file."); // We used \ five times here
    println!(r#"He said, "You can find the file at c:\files\my_documents\file.txt." Then I found the file."#)
}

这打印的是同样的东西,但使用 r# 使人类更容易阅读。

He said, "You can find the file at c:\files\my_documents\file.txt." Then I found the file.
He said, "You can find the file at c:\files\my_documents\file.txt." Then I found the file.

如果你需要在里面打印#,那么你可以用r##开头,用##结尾。如果你需要打印多个连续的#,可以在每边多加一个#。

下面是四个例子。

fn main() {

    let my_string = "'Ice to see you,' he said."; // single quotes
    let quote_string = r#""Ice to see you," he said."#; // double quotes
    let hashtag_string = r##"The hashtag #IceToSeeYou had become very popular."##; // Has one # so we need at least ##
    let many_hashtags = r####""You don't have to type ### to use a hashtag. You can just use #.""####; // Has three ### so we need at least ####

    println!("{}\n{}\n{}\n{}\n", my_string, quote_string, hashtag_string, many_hashtags);

}

这将打印:

'Ice to see you,' he said.
"Ice to see you," he said.
The hashtag #IceToSeeYou had become very popular.
"You don't have to type ### to use a hashtag. You can just use #."

r#还有另一个用途:使用它,你可以使用关键字(如letfn等)作为变量名。

fn main() {
    let r#let = 6; // The variable's name is let
    let mut r#mut = 10; // This variable's name is mut
}

r#之所以有这个功能,是因为旧版本的Rust的关键字比现在的Rust少。所以有了r#就可以避免以前不是关键字的变量名的错误。

又或者因为某些原因,你确实需要一个函数的名字,比如return。那么你可以这样写:

fn r#return() -> u8 {
    println!("Here is your number.");
    8
}

fn main() {
    let my_number = r#return();
    println!("{}", my_number);
}

这样打印出来的结果是:

Here is your number.
8

所以你可能不需要它,但是如果你真的需要为一个变量使用一个关键字,那么你可以使用r#

如果你想打印&strchar的字节,你可以在字符串前写上b就可以了。这适用于所有ASCII字符。这些是所有的ASCII字符。

☺☻♥♦♣♠♫☼►◄↕‼¶§▬↨↑↓→∟↔▲▼123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

所以,当你打印这个

fn main() {
    println!("{:?}", b"This will look like numbers");
}

这就是结果:

[84, 104, 105, 115, 32, 119, 105, 108, 108, 32, 108, 111, 111, 107, 32, 108, 105, 107, 101, 32, 110, 117, 109, 98, 101, 114, 115]

对于char来说,这叫做一个字节,对于&str来说,这叫做一个字节字符串

如果你需要的话,也可以把br放在一起。

fn main() {
    println!("{:?}", br##"I like to write "#"."##);
}

这将打印出 [73, 32, 108, 105, 107, 101, 32, 116, 111, 32, 119, 114, 105, 116, 101, 32, 34, 35, 34, 46]

还有一个Unicode转义,可以让你在字符串中打印任何Unicode字符: \u{}{}里面有一个十六进制数字可以打印。下面是一个简短的例子,说明如何获得Unicode数字,以及如何再次打印它。

fn main() {
    println!("{:X}", '행' as u32); // Cast char as u32 to get the hexadecimal value
    println!("{:X}", 'H' as u32);
    println!("{:X}", '居' as u32);
    println!("{:X}", 'い' as u32);

    println!("\u{D589}, \u{48}, \u{5C45}, \u{3044}"); // Try printing them with unicode escape \u
}

我们知道,println!可以和{}(用于显示)或{:?}(用于调试)一起打印,再加上{:#?}就可以进行漂亮的打印。但是还有很多其他的打印方式。

例如,如果你有一个引用,你可以用{:p}来打印指针地址。指针地址指的是电脑内存中的位置。

fn main() {
    let number = 9;
    let number_ref = &number;
    println!("{:p}", number_ref);
}

这可以打印0xe2bc0ffcfc或其他地址。每次可能都不一样,这取决于你的计算机存储的位置。

或者你可以打印二进制、十六进制和八进制。

fn main() {
    let number = 555;
    println!("Binary: {:b}, hexadecimal: {:x}, octal: {:o}", number, number, number);
}

这将打印出Binary: 1000101011, hexadecimal: 22b, octal: 1053

或者你可以添加数字来改变顺序。第一个变量将在索引0中,下一个在索引1中,以此类推。

fn main() {
    let father_name = "Vlad";
    let son_name = "Adrian Fahrenheit";
    let family_name = "Țepeș";
    println!("This is {1} {2}, son of {0} {2}.", father_name, son_name, family_name);
}

father_name在0位,son_name在1位,family_name在2位。所以它打印的是This is Adrian Fahrenheit Țepeș, son of Vlad Țepeș

也许你有一个非常复杂的字符串要打印,{}大括号内有太多的变量。或者你需要不止一次的打印一个变量。那么在{}中添加名称就会有帮助。

fn main() {
    println!(
        "{city1} is in {country} and {city2} is also in {country},
but {city3} is not in {country}.",
        city1 = "Seoul",
        city2 = "Busan",
        city3 = "Tokyo",
        country = "Korea"
    );
}

这样就可以打印了。

Seoul is in Korea and Busan is also in Korea,
but Tokyo is not in Korea.

如果你愿意,也可以在Rust中进行非常复杂的打印。下面展示怎样做:

{variable:padding alignment minimum.maximum}

要理解这一点,请看

  1. 你想要一个变量名吗?先写出来,就像我们上面写{country}一样。 (如果你想做更多的事情,就在后面加一个:)
  2. 你想要一个填充字符吗?例如,55加上三个 "填充零"就像00055。
  3. padding的对齐方式(左/中/右)?
  4. 你想要一个最小长度吗?(写一个数字就可以了)
  5. 你想要一个最大长度吗?(写一个数字,前面有一个.)

例如,我想写 "a",左边有五个ㅎ,右边有五个ㅎ。

fn main() {
    let letter = "a";
    println!("{:ㅎ^11}", letter);
}

这样打印出来的结果是ㅎㅎㅎㅎㅎaㅎㅎㅎㅎㅎ。我们看看1)到5)的这个情况,就能明白编译器是怎么解读的:

  • 你要不要变量名?{:ㅎ^11}没有变量名。:之前没有任何内容。
  • 你需要一个填充字符吗?{:ㅎ^11} 是的:ㅎ"在:后面,有一个^<表示变量在填充字符左边,>表示在填充字符右边,^表示在填充字符中间。
  • 要不要设置最小长度?{:ㅎ^11}是:后面有一个11。
  • 你想要一个最大长度吗?{:ㅎ^11} 不是:前面没有.的数字。

下面是多种类型的格式化的例子:

fn main() {
    let title = "TODAY'S NEWS";
    println!("{:-^30}", title); // no variable name, pad with -, put in centre, 30 characters long
    let bar = "|";
    println!("{: <15}{: >15}", bar, bar); // no variable name, pad with space, 15 characters each, one to the left, one to the right
    let a = "SEOUL";
    let b = "TOKYO";
    println!("{city1:-<15}{city2:->15}", city1 = a, city2 = b); // variable names city1 and city2, pad with -, one to the left, one to the right
}

它打印出来了。

---------TODAY'S NEWS---------
|                            |
SEOUL--------------------TOKYO