Crate & Module
Crate
定義在Cargo.toml
裡,指向Rust社群的套件庫,crago build
時會先去crates.io抓對應的套件下來
note
crago build
預設會安裝到$HOME/.cargo/bin
Cargo.toml
[dependency]
num = "0.4"
image = "0.13"
Use Package
這裡指的套件(Package),泛指可被引用的目標
- In Project 在同一個專案內引用同為這個專案開發的其他套件
- Vendors
使用第三方開發的套件,以語言生態系不同,大致又分為
有託管
跟無託管
兩種目喲
Folder | File | |
---|---|---|
Rust | Crate | Module |
Go | Workspace/Package | 檔名不重要,重要的是code第一行的package宣告 |
Python | Package | Module |
In Project File
- Rust
- Go
專案目錄會被稱為Crate Root,使用mod
作為namespace並引用進其他file的內容
main.rs
mod hello;
fn main() {
hello::say_hello();
}
hello.rs
pub fn say_hello() {
println!("Hello, world!");
}
Go以source code檔案的package
定義決定是不是同屬一個package,相同package的不同檔案並不重要也不需要import
hello.go
package main
import "fmt"
func SayHello() {
fmt.Println("Hello")
}
main.go
package main
func main() {
SayHello()
}
In Project Folder
- Rust mod keyword
- Rust mod.rs
- Rust Nested Mod
- Go Mod
寫在同一個檔案,用mod
關鍵字坎套
main.rs
mod foo {
fn say_foo() {
println!("This is Foo");
}
}
fn main() {
foo::say_foo();
}
./foo/mod.rs
pub fn say_foo() {
println!("This is Foo");
}
./main.rs
use foo;
fn main() {
foo::say_foo();
}
./foo/moo.rs
pub fn say_moo() {
println!("This is Foo's Moo");
}
./foo.rs
pub mod moo;
./main.rs
use foo;
fn main() {
foo::moo::say_foo();
}
go的子資料夾內的source code,被視為目前的workspace下的另一個Go Module
./foo/foo.go
package foo
import "fmt"
func SayFoo() {
fmt.Println("This is Foo")
}
main.go
package main
import "lab1/foo"
func main() {
foo.SayFoo()
}
Vendors Package
- Rust
- Go
依賴Cargo.toml
內的dependency,從crates.io
上裝下來。使用直接import crate name就可以使用
也可以直接裝沒有在crates.io上的Git repo
cargo install --git github.com/mechsix/rustexample
main.rs
use image::io::Reader;
fn main() {
let img = Reader::open("example.png")?.decode()?;
// ...
}
Go因為沒有集中的Package Service
Vendor套件與資料夾的做法相 同,Go的Mod基本上都是全域的絕對路徑
main.go
package main
import "github.com/mechsix/goexample"
func main() {
goexample.Hello()
}
Unit Test
Rust的test是使用tests
mod,可以直接寫在code旁
#[cfg(test)]
mod tests {
// Note this useful idiom: importing names from outer (for mod tests) scope.
use super::*;
#[test]
fn test_add() {
assert_eq!(add(1, 2), 3);
}
}
使用crate
可以這樣直接執行。這預設會將所有的STDOUT
隱藏起來
$ crate test
若想要執行test時保留STDOUT
到console,可以這樣下
$ crate test -- --nocapture