官术网_书友最值得收藏!

1.3 Rust初體驗

在本節內容中,你將初次體驗Rust。我們首先要了解如何使用編譯器,然后會快速編寫一個程序。在接下來的章節中,我們會寫一個完整的項目。


注意 要安裝Rust,需要使用官方提供的安裝器(installer)進行安裝。請登錄Rust官方網站并下載。


1.3.1 直通“Hello, world!”

大多數程序員在接觸一門新的語言時,要做的第一件事就是學習如何在控制臺上輸出“Hello,world!”。接下來你也需要這樣做。在遇到令人討厭的語法錯誤之前,你要先驗證所有環境是否已經準備就緒。

如果你使用的是Windows系統,在安裝完Rust以后,請通過開始菜單打開命令提示符窗口。然后請執行以下命令:

C:\> cd %TMP%

如果你使用的是Linux或macOS系統,請打開一個終端窗口。打開后,請執行以下命令:

$ cd $TMP

從這里開始,所有操作系統的命令應該是相同的。如果你的Rust環境安裝正確,那么執行以下3個命令,將會在屏幕上輸出“Hello,world!”(以及一些其他輸出)。

$ cargo new hello
$ cd hello
$ cargo run

這是在Windows上執行cmd.exe進入命令行提示符窗口以后,執行整個會話過程的示例:

C:\> cd %TMP%
C:\Users\Tim\AppData\Local\Temp\> cargo new hello
Created binary (application) 'hello' project
C:\Users\Tim\AppData\Local\Temp\> cd hello
C:\Users\Tim\AppData\Local\Temp\hello\> cargo run
Compiling hello v0.1.0 (file:///C:/Users/Tim/AppData/Local/Temp/hello)
Finished debug [unoptimized + debuginfo] target(s) in 0.32s
Running 'target\debug\hello.exe'
Hello, world!

類似地,在Linux或macOS上,你的控制臺上顯示的信息應該像下面這樣:

$ cd $TMP
$ cargo new hello
Created binary (application) 'hello' package
$ cd hello
$ cargo run
Compiling hello v0.1.0 (/tsm/hello)
Finished dev [unoptimized + debuginfo] target(s) in 0.26s
Running 'target/debug/hello'
Hello, world!

如果你走到了這一步,那就太棒了!你已經運行了自己的第一段Rust代碼,而且并不需要編寫多少Rust代碼。接下來,讓我們來看看在整個過程中都發生了什么。

Rust的cargo工具既提供了一個構建系統,又提供了包管理器。這意味著cargo知道如何將Rust代碼轉換成可執行的二進制文件,同時能夠管理項目依賴包的下載和編譯的過程。

cargo new會遵照標準模板創建一個項目。執行tree命令就能清楚地看到在執行cargo new之后默認的項目目錄結構,以及創建出的那些文件:

$ tree hello
hello
├──Cargo.toml
└──src
└──main.rs
1 directory, 2 files

用cargo創建出來的所有Rust項目有著相同的結構。在項目的根目錄中,名為Cargo.toml的文件描述了項目的元數據,例如項目的名稱、項目的版本號及其依賴項。源代碼保存在src目錄中。Rust源文件使用.rs作為它的文件擴展名。要想查看cargo new創建出來的那些文件,可以使用tree命令。

接下來,你要執行的命令是cargo run。這個操作對你來說很容易掌握,然而cargo實際上做的工作比你以為的要多得多。你要求cargo去運行此項目。在調用此命令時,還沒有任何實際可執行的程序文件存在,它決定使用調試模式(debug mode)來為你編譯代碼,這樣可以提供最大化的錯誤信息(error information)。碰巧的是,src/main.rs文件總是會包含一個“Hello,world!”作為初始代碼。編譯的結果是一個名為hello(或hello.exe)的文件。緊接著它會執行這個文件,并把執行結果輸出到屏幕上。

執行cargo run以后,項目還會增加一些新的文件。現在,在項目的根目錄中會有一個Cargo.lock文件,還有一個target/目錄。這兩者都是由cargo管理的。因為它們都是編譯過程中的產物,所以可以不予理會。Cargo.lock文件指定了所有依賴項的具體版本號,所以程序總會使用同樣的方式,可靠地構建將來的程序版本,直到Cargo.toml的內容被修改才會改變這種構建的方式。

在執行cargo run來編譯項目以后,再次執行tree命令來查看新的目錄結構:

$ tree --dirsfirst hello
hello
├──src
│  └── main.rs
├──target
│  └── debug
│      ├──build
│      ├──deps
│      ├──examples
│      ├──native
│      └──hello
├──Cargo.lock
└──Cargo.toml

至此,所有步驟能正常運行了,很好!我們已經走捷徑直通“Hello, world!”,接下來讓我們走一條稍遠點兒的路,再次到達這里。

1.3.2 第一個Rust程序

作為第一個Rust程序,我們想編寫代碼,用于輸出以下文本信息:

Hello, world!
Grü? Gott!
ハロー?ワールド

在本書的Rust之旅中,你應該已經見過此輸出內容的第一行了。另外的兩行是為了展示出Rust的以下特點:易用的迭代和內置對Unicode的支持。與1.3.1節中的程序一樣,在這個程序中我們會使用cargo。具體步驟如下。

(1)打開控制臺窗口。

(2)如果是在Windows上,就執行cd %TMP%;如果在其他操作系統上,就執行cd $TMP。

(3)執行cargo new hello2命令,創建一個新項目。

(4)執行cd hello2命令,移動到此項目的根目錄中。

(5)在一個文本編輯器中打開src/main.rs文件。

(6)用清單1.1中的內容替換該文件中的文本。

清單1.1的源代碼參見ch1/ch1-hello2/src/hello2.rs。

清單1.1 用3種語言說“Hello,world!”

 1 fn greet_world() {
2     println!("Hello, world!");    ?---  這里的第一個感嘆號表示這是一個宏,這個我們稍后會討論。
3     let southern_germany = "Grü? Gott!";    ?---  Rust中的賦值,更恰當的說法叫作變量綁定,使用let關鍵字。
4     let japan = "ハロー?ワールド";    ?---  對Unicode的支持,是“開箱即用”的。
5     let regions = [southern_germany, japan];    ?---  數組字面量使用方括號。
6     for region in regions.iter() {    ?---  很多類型都有iter()方法,此方法會返回一個迭代器。
7             println!("{}", &region);    ?---  此處的和符號(&)表示“借用”region的值,用于只讀的訪問。
8     }
9 }
10
11 fn main() {
12     greet_world();    ?---  調用一個函數。要注意緊跟在函數名后面的圓括號。
13 }

現在,代碼更新了,只需在hello2/目錄里執行cargo run,你應該能看到這3個問候語(它們出現在cargo自己的一些輸出的后面),如下所示:

$ cargo run
Compiling hello2 v0.1.0 (/path/to/ch1/ch1-hello2)
Finished dev [unoptimized + debuginfo] target(s) in 0.95s
Running 'target/debug/hello2'
Hello, world!
Grü? Gott!
ハロー?ワールド

讓我們花點兒時間來談談清單1.1中一些有意思的語言元素。

在這個例子里,你可能最先注意到的就是,Rust中的字符串能夠包含許多不同的字符。在Rust中,字符串能夠確保是有效的UTF-8編碼。這意味著你可以相對輕松地使用非英語的語言。

有一個字符看起來會有點兒奇怪,就是println后面的感嘆號。如果你用Ruby編寫過程序,可能就會習慣性地認為它表示一個破壞性的操作。然而在Rust中,它表示的是使用一個。就現在來講,你可以把宏看作一類奇特的函數,其提供了避免“樣板代碼”(boilerplate code)的能力。對于本例中的println!宏來說,實際上它在底層進行了大量的類型檢測工作,所以才能把任意的數據類型輸出到屏幕上。

主站蜘蛛池模板: 闻喜县| 寿宁县| 丰顺县| 大姚县| 三门峡市| 延吉市| 保德县| 泸西县| 盐边县| 明水县| 五峰| 阿坝县| 渭源县| 周宁县| 巴中市| 岐山县| 修水县| 栾城县| 门头沟区| 秭归县| 蒙山县| 潼关县| 开原市| 谷城县| 德阳市| 新兴县| 岳普湖县| 盐边县| 白玉县| 五指山市| 西安市| 奎屯市| 剑河县| 巧家县| 三台县| 湘潭市| 铜梁县| 荣成市| 昌邑市| 龙井市| 峨山|