fn main() { println!("hello rust");}
Facebookの天秤座プロジェクトが出てきたと、突然火錆の全ては、錆これは史上最大規模のプロジェクトですが、世界的なデジタル通貨の上昇に伴って、錆の旅は始まったばかりかもしれません。
あなたは錆についての多くが、開発者の目には、錆が実際に香りを知らないかもしれませんが!4年連続では、スタックオーバーフローの開発者は、「好きなプログラミング言語」賞、錆が最初です。
2015年5月15日、錆が正式バージョン1.0をリリースしました。4年間は、その「安全保障」と「高い同時実行」の二つの特徴のおかげで、より多くの開発者に愛され続けています。錆正は、潜在的な新しいプロジェクトがブロックチェーン市場を占領雷鳴、多くの有名な古いプロジェクトはまた、錆を書き換える切り替えを検討しています。
錆の言語機能(セキュリティ、高パフォーマンス、並行プログラミング)とブロック鎖(暗号化、分散、セキュリティに敏感な)自然なフィット感の特性、多くの有名なブロックチェーンプロジェクトは、開発言語として錆を使用することを選択した、を含む:パリティ、水玉、基板、イーサリアムクラシックグリン、Holochain、カルダーノ・錆、Exonum、灯台、Nimiq、Nervos、コンフラックス、錆、Codechain、Witnetなどは、今後の天秤座は言うまでもありません。
最初のブロック鎖開発言語プロジェクトとして錆を使用するための選択肢は、より多くの、私たちは錆言語学習クライマックスの波の到来を告げるだろうと信じている、と給与計算ブロックチェーンの開発者どのように高く、私たちは皆知っていると信じて。
-実験[無料]錆チュートリアルの二階のライン「錆は一例で学びます」。コースから適応古典の教科書「錆例」、および教材に基づいて、テストや課題をオンライン試験環境を構成しました。各点は、小さな例の完全な知識を持っていると演習は、それが簡単に言語を習得するために作ります。
友人はをクリックすることができます学びたい「の例で錆を学ぶ」ああ。
次に、我々は錆は、右、少しで錆があなたの最初のプログラムを作成するいくつかの基本的な文法を理解するために私と一緒に行きました。
あなたは常に基本的な錆についての知識を統合するために考え出すことができるように、この論文では、そのコレクションを推奨しています。
以下は、「例で学ぶ錆」セクション1:
簡単な紹介
錆は、安全性に焦点(安全性)、速度(スピード)と並行処理(同時実行)最近のシステムのプログラミング言語です。錆セキュリティを通じて上記の目的を達成するためのメモリ、ないガベージコレクション(ガベージコレクション、GC)。
このコースは、オンライン実験手順の例の一連のエントリ錆プログラミング言語を完了するためのステップバイステップの「ラストは一例で学ぶ」、実験のオンライン版です。実験のオンライン版 - 、カリキュラムの改訂と改善倉庫、倉庫の住所に参加錆が例で学ぶ見にようこそ。元の文書(著作権MITやApacheのプロトコル協定)の著作権は中国語と英語をフォローする全てのコンテンツの著作権のドキュメント。
知識ポイント
このセクションの主な内容は、以下の実験の知識が含まれています。
- コース
- 最初のプログラムの書き方
- 詳細なHello Worldのプログラム
- 注記
- 書式付き出力
こんにちは世界
私たちの最初のプログラムは、以下が完全なプログラムコードであり、プロセスを実行するためにコンパイルされ、「Hello World」のメッセージの凡例を表示します。
これは、伝統的なHello Worldのプログラムのソースです。まず、下の/ home /プロジェクトディレクトリWebIDE hello.rsファイルを構築する新しい研究室、次のコードを記述(先頭のコメント//の内容に入力する必要はありません):
// 这是注释内容,将会被编译器忽略掉
// 可以单击那边的按钮 "Run" 来测试这段代码 ->
// 若想用键盘操作,可以使用快捷键 "Ctrl + Enter" 来运行
// 这段代码支持编辑,你可以自由地修改代码!
// 通过单击 "Reset" 按钮可以使代码恢复到初始状态 ->
// 这是主函数
fn main() {
// 调用编译生成的可执行文件时,这里的语句将被运行。
// 将文本打印到控制台
println!("Hello World!");
}
println!マクロ(マクロ)で、テキストは、コンソール(コンソール)に出力することができます。
実験では、次のコマンドはターミナルビルをWebIDE、A錆rustcコンパイラのソースから実行ファイルを生成します。
$ cd /home/project
$ rustc hello.rs
使用rustcコンパイル後、実行可能ファイルのハローを取得し、ハロー生成されたファイルを実行するには、次のコマンドを使用します。
$ ./hello
次のように実行結果は次のとおりです。
手を試してみてください
再びマクロのprintlnを使用して、あなたのhello.rsプログラムのコードの次の行を増やすようにしてください、次のような結果を得ます!:
Hello World!
I'm a Rustacean!
注記
ノートには、任意のプログラムのために不可欠であり、錆同じサポートいくつかの異なる方法コメント。
一般的なコメントは、外にコンパイラによって無視されている内容:
- //単一行コメントは、その行のコンテンツの終わりまで。
/ *終了デリミタまでのブロックコメントの注釈内容。* /
ドキュメントコメントは、内容がHTMLヘルプファイルに解析されます。
- ///は、次期のヘルプファイルを生成します。
- 項目の//コメントは、(注釈クレート、モジュール、または機能など)のヘルプファイルを生成します!:属します。
fn main() {
// 这是行注释的例子
// 注意有两个斜线在本行的开头
// 在这里面的所有内容都不会被编译器读取
// println!("Hello, world!");
// 请运行一下,你看到结果了吗?现在请将上述语句的两条斜线删掉,并重新运行。
/*
* 这是另外一种注释——块注释。一般而言,行注释是推荐的注释格式,
* 不过块注释在临时注释大块代码特别有用。/* 块注释可以 /* 嵌套, */ */
* 所以只需很少按键就可注释掉这些 main() 函数中的行。/*/*/* 自己试试!*/*/*/
*/
/*
注意,上面的例子中纵向都有 `*`,这只是一种风格,实际上这并不是必须的。
*/
// 观察块注释是如何简单地对表达式进行修改的,行注释则不能这样。
// 删除注释分隔符将会改变结果。
let x = 5 + /* 90 + */ 5;
println!("Is `x` 10 or 100? x = {}", x);
}
書式付き出力
STDは:: fmtを備え、マクロによって内部で定義されたプロセスを操作を印刷します:
- 書き込みフォーマットされたテキストフォーマット:!の文字列(String)を。注釈:パラメータ文字列が戻り値ではありません。
- 印刷:!似た形式が、コンソールに出力テキスト(IO :: STDOUT)!。
- println:!と印刷似ていますが、出力は改行文字を追加!。
- イープリント:!標準誤差(IO :: stderr)に、フォーマット似ていますが、テキスト出力!。
- eprintln!:イープリントと似ていますが、出力は改行文字を付加します。
これらのマクロは、同じアプローチ(パース)のテキストで解析されます。もう一つの利点は、コンパイル時に正しさのチェックをフォーマットされています。
新format.rsファイルは、書き込みコードは次の通り。
fn main() {
// 通常情况下,`{}` 会被任意变量内容所替换。
// 变量内容会转化成字符串。
println!("{} days", 31);
// 不加后缀的话,31 就自动成为 i32 类型。
// 你可以添加后缀来改变 31 的类型。
// 用变量替换字符串有多种写法。
// 比如可以使用位置参数。
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
// 可以使用命名参数。
println!("{subject} {verb} {object}",
object="the lazy dog",
subject="the quick brown fox",
verb="jumps over");
// 可以在 `:` 后面指定特殊的格式。
println!("{} of {:b} people know binary, the other half don't", 1, 2);
// 你可以按指定宽度来右对齐文本。
// 下面语句输出 " 1",5 个空格后面连着 1。
println!("{number:>width$}", number=1, width=6);
// 你可以在数字左边补 0。下面语句输出 "000001"。
println!("{number:>0width$}", number=1, width=6);
// println! 会检查使用到的参数数量是否正确。
println!("My name is {0}, {1} {0}", "Bond");
// 改正 ^ 补上漏掉的参数:"James"
// 创建一个包含单个 `i32` 的结构体(structure)。命名为 `Structure`。
#[allow(dead_code)]
struct Structure(i32);
// 但是像结构体这样的自定义类型需要更复杂的方式来处理。
// 下面语句无法运行。
println!("This struct `{}` won't print...", Structure(3));
// 改正 ^ 注释掉此行。
}
std :: FMTは、形質の様々なが含まれているコントロールのテキスト表示は、次の2つの形式の重要な基本的な特性の一つに(特色「の特徴、特性」や他の手段を持っています):
- FMT ::デバッグ:使用{:}?マーク。デバッグに使用するテキストの書式を設定します。
- FMT ::ディスプレイ:{}タグを使用。よりエレガントでフレンドリーなスタイルでテキストの書式を設定します。
用途上記の例では、fmtを::表示を、標準ライブラリが実装のこれらのタイプを提供するため。テキストのカスタム型を印刷するには、より多くのステップが必要とされています。
手を試してみてください
- (「正しい」のコードのコメントを参照してください)、それは間違って実行することはできません上記のコードで2つのエラーを修正するには。
- !のprintlnマクロ、印刷する小数点以下の桁数の表示を制御すること:Piはおおよそ3.142である(Piが約3.142に等しいです)。運動の目的を達成するためには、円周率の近似値としてPI = 3.141592使用してみましょう。
ヒント:セット小数点以下の桁数の表示形式は、ドキュメントのstd :: FMTを参照することができます。
デバッグ(デバッグ)
すべての種類は、あなたが必要とされる特性この特性を達成するためにプリントアウトのstd :: fmtは、書式を使用したい場合。のみ、このようなタイプのstdライブラリなどのいくつかのタイプを提供するために、自動実装。他のすべてのタイプを手動で実装する必要があります。
FMT ::デバッグこの作業は非常に簡単になるようにするこの特性。すべてのタイプのFMT ::デバッグを実現するために(自動的に作成された派生を)導出することができます。しかし、FMT ::ディスプレイのマニュアルを実装する必要があります。
// 这个结构体不能使用 `fmt::Display` 或 `fmt::Debug` 来进行打印。
struct UnPrintable(i32);
// `derive` 属性会自动创建所需的实现,使这个 `struct` 能使用 `fmt::Debug` 打印。
#[derive(Debug)]
struct DebugPrintable(i32);
{?:}印刷するにはSTDライブラリを使用することができ、すべての種類を持って生まれています。新format1.rsファイルには、次のコードを記述します。
// 推导 `Structure` 的 `fmt::Debug` 实现。
// `Structure` 是一个包含单个 `i32` 的结构体。
#[derive(Debug)]
struct Structure(i32);
// 将 `Structure` 放到结构体 `Deep` 中。然后使 `Deep` 也能够打印。
#[derive(Debug)]
struct Deep(Structure);
fn main() {
// 使用 `{:?}` 打印和使用 `{}` 类似。
println!("{:?} months in a year.", 12);
println!("{1:?} {0:?} is the {actor:?} name.",
"Slater",
"Christian",
actor="actor's");
// `Structure` 也可以打印!
println!("Now {:?} will print!", Structure(3));
// 使用 `derive` 的一个问题是不能控制输出的形式。
// 假如我只想展示一个 `7` 怎么办?
println!("Now {:?} will print!", Deep(Structure(7)));
}
実験室の建物でプログラムをコンパイルして実行するターミナルWebIDE。
$ rustc format1.rs
$ ./format1
次のように実行結果は以下のとおりです。
FMTだから::デバッグは本当にそのコンテンツを印刷することが可能にするが、犠牲いくつかの美しさ。錆もで{:?#}「美化プリント」機能を提供します。
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "Peter";
let age = 27;
let peter = Person { name, age };
// 美化打印
println!("{:#?}", peter);
}
次のようにformat1.rsに上記のコードを追加した後、結果は、コンパイルと実行します。
手動で::ディスプレイのFMT達成するための表示を制御することができます。
ディスプレイ(表示)
FMT ::デバッグは、一般的にシンプルで、外観を見て、したがって、出力がしばしば望ましいカスタマイズしません。これは、ニーズ手動FMT ::表示を実現するために行われます。{}内のFMT ::ディスプレイ番号。実装は次のようになります。
// (使用 `use`)导入 `fmt` 模块使 `fmt::Display` 可用
use std::fmt;
// 定义一个结构体,咱们会为它实现 `fmt::Display`。以下是个简单的元组结构体
// `Structure`,包含一个 `i32` 元素。
struct Structure(i32);
// 为了使用 `{}` 标记,必须手动为类型实现 `fmt::Display` trait。
impl fmt::Display for Structure {
// 这个 trait 要求 `fmt` 使用与下面的函数完全一致的函数签名
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// 仅将 self 的第一个元素写入到给定的输出流 `f`。返回 `fmt:Result`,此
// 结果表明操作成功或失败。注意 `write!` 的用法和 `println!` 很相似。
write!(f, "{}", self.0)
}
}
fmt::Display 的效果可能比 fmt::Debug 简洁,但对于 std 库来说,这就有一个问题。模棱两可的类型该如何显示呢?举个例子,假设标准库对所有的 Vec
- Vec
:/:/etc:/home/username:/bin(使用 : 分割) - Vec
:1,2,3(使用 , 分割)
我们没有这样做,因为没有一种合适的样式适用于所有类型,标准库也并不擅自规定一种样式。对于 Vec
这并不是一个问题,因为对于任何非泛型的容器类型, fmt::Display 都能够实现。新建 display.rs 文件,编写代码如下:
use std::fmt; // (使用 `use`)导入 `fmt` 模块使 `fmt::Display` 可用
// 带有两个数字的结构体。推导出 `Debug`,以便与 `Display` 的输出进行比较。
#[derive(Debug)]
struct MinMax(i64, i64);
// 实现 `MinMax` 的 `Display`。
impl fmt::Display for MinMax {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// 使用 `self.number` 来表示各个数据。
write!(f, "({}, {})", self.0, self.1)
}
}
// 为了比较,定义一个含有具名字段的结构体。
#[derive(Debug)]
struct Point2D {
x: f64,
y: f64,
}
// 类似地对 `Point2D` 实现 `Display`
impl fmt::Display for Point2D {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// 自定义格式,使得仅显示 `x` 和 `y` 的值。
write!(f, "x: {}, y: {}", self.x, self.y)
}
}
fn main() {
let minmax = MinMax(0, 14);
println!("Compare structures:");
println!("Display: {}", minmax);
println!("Debug: {:?}", minmax);
let big_range = MinMax(-300, 300);
let small_range = MinMax(-3, 3);
println!("The big range is {big} and the small is {small}",
small = small_range,
big = big_range);
let point = Point2D { x: 3.3, y: 7.2 };
println!("Compare points:");
println!("Display: {}", point);
println!("Debug: {:?}", point);
// 报错。`Debug` 和 `Display` 都被实现了,但 `{:b}` 需要 `fmt::Binary`
// 得到实现。这语句不能运行。
// println!("What does Point2D look like in binary: {:b}?", point);
}
程序运行的结果如下所示:
fmt::Display 被实现了,而 fmt::Binary 没有,因此 fmt::Binary 不能使用。 std::fmt 有很多这样的 trait,它们都要求有各自的实现。这些内容将在 后面的 std::fmt 章节中详细介绍。
动手试一试
检验上面例子的输出,然后在示例程序中,仿照 Point2D 结构体增加一个复数结构体。使用一样的方式打印,输出结果要求是这个样子:
Display: 3.3 + 7.2i
Debug: Complex { real: 3.3, imag: 7.2 }
测试实例:List
对一个结构体实现 fmt::Display,其中的元素需要一个接一个地处理到,这可能会很麻烦。问题在于每个 write! 都要生成一个 fmt::Result。正确的实现需要处理所有的 Result。Rust 专门为解决这个问题提供了 ? 操作符。
在 write! 上使用 ? 会像是这样:
// 对 `write!` 进行尝试(try),观察是否出错。若发生错误,返回相应的错误。
// 否则(没有出错)继续执行后面的语句。
write!(f, "{}", value)?;
另外,你也可以使用 try! 宏,它和 ? 是一样的。这种写法比较罗嗦,故不再推荐, 但在老一些的 Rust 代码中仍会看到。使用 try! 看起来像这样:
try!(write!(f, "{}", value));
有了 ?,对一个 Vec 实现 fmt::Display 就很简单了。新建 vector.rs 文件,编写代码如下:
use std::fmt; // 导入 `fmt` 模块。
// 定义一个包含单个 `Vec` 的结构体 `List`。
struct List(Vec<i32>);
impl fmt::Display for List {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// 使用元组的下标获取值,并创建一个 `vec` 的引用。
let vec = &self.0;
write!(f, "[")?;
// 使用 `v` 对 `vec` 进行迭代,并用 `count` 记录迭代次数。
for (count, v) in vec.iter().enumerate() {
// 对每个元素(第一个元素除外)加上逗号。
// 使用 `?` 或 `try!` 来返回错误。
if count != 0 { write!(f, ", ")?; }
write!(f, "{}", v)?;
}
// 加上配对中括号,并返回一个 fmt::Result 值。
write!(f, "]")
}
}
fn main() {
let v = List(vec![1, 2, 3]);
println!("{}", v);
}
程序运行的结果如下:
动手试一试:
更改程序使 vector 里面每个元素的下标也能够打印出来。新的结果如下:
[0: 1, 1: 2, 2: 3]
格式化
我们已经看到,格式化的方式是通过格式字符串来指定的:
- format!("{}", foo) -> "3735928559"
- format!("0x{:X}", foo) -> "0xDEADBEEF"
- format!("0o{:o}", foo) -> "0o33653337357"
根据使用的参数类型是 X、o 还是未指定,同样的变量(foo)能够格式化成不同的形式。
这个格式化的功能是通过 trait 实现的,每种参数类型都对应一种 trait。最常见的格式化 trait 就是 Display,它可以处理参数类型为未指定的情况,比如 {}。
新建 format2.rs 文件,编写代码如下:
use std::fmt::{self, Formatter, Display};
struct City {
name: &'static str,
// 纬度
lat: f32,
// 经度
lon: f32,
}
impl Display for City {
// `f` 是一个缓冲区(buffer),此方法必须将格式化后的字符串写入其中
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' };
let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' };
// `write!` 和 `format!` 类似,但它会将格式化后的字符串写入
// 一个缓冲区(即第一个参数f)中。
write!(f, "{}: {:.3}°{} {:.3}°{}",
self.name, self.lat.abs(), lat_c, self.lon.abs(), lon_c)
}
}
#[derive(Debug)]
struct Color {
red: u8,
green: u8,
blue: u8,
}
fn main() {
for city in [
City { name: "Dublin", lat: 53.347778, lon: -6.259722 },
City { name: "Oslo", lat: 59.95, lon: 10.75 },
City { name: "Vancouver", lat: 49.25, lon: -123.1 },
].iter() {
println!("{}", *city);
}
for color in [
Color { red: 128, green: 255, blue: 90 },
Color { red: 0, green: 3, blue: 254 },
Color { red: 0, green: 0, blue: 0 },
].iter() {
// 在添加了针对 fmt::Display 的实现后,请改用 {} 检验效果。
println!("{:?}", *color)
}
}
程序运行的结果如下:
在 fmt::fmt 文档中可以查看格式化 traits 一览表和它们的参数类型。
动手试一试
为上面的 Color 结构体实现 fmt::Display,应得到如下的输出结果:
RGB (128, 255, 90) 0x80FF5A
RGB (0, 3, 254) 0x0003FE
RGB (0, 0, 0) 0x000000
如果感到疑惑,可看下面两条提示:
- 你可能需要多次列出每个颜色,
- 你可以使用 :02 补零使位数为 2 位。
实验总结
本节实验中我们学习了以下的内容:
- 课程介绍
- 如何编写第一个程序
- Hello World 程序详解
- 注释
- 格式化输出
还想继续学习的小伙伴,点击 《通过例子学 Rust》, 免费学!