Rust by Example - страница 33
>
>}
Let's check that things still work as before:
>$ rustc split.rs && ./split
>called `my::function()`
>called `function()`
>called `my::indirect_access()`, that
>> called `my::private_function()`
>called `my::nested::function()`
A crate is a compilation unit in Rust. Whenever rustc some_file.rs is called, some_file.rs is treated as the crate file. If some_file.rs has mod declarations in it, then the contents of the module files would be inserted in places where mod declarations in the crate file are found, before running the compiler over it. In other words, modules do not get compiled individually, only crates get compiled.
A crate can be compiled into a binary or into a library. By default, rustc will produce a binary from a crate. This behavior can be overridden by passing the --crate-type flag to lib.
Let's create a library, and then see how to link it to another crate.
>pub fn public_function() {
>println!("called rary's `public_function()`");
>}
>fn private_function() {
>println!("called rary's `private_function()`");
>}
>pub fn indirect_access() {
>print!("called rary's `indirect_access()`, that\n> ");
>private_function();
>}
>$ rustc --crate-type=lib rary.rs
>$ ls lib*
>library.rlib
Libraries get prefixed with "lib", and by default they get named after their crate file, but this default name can be overridden by passing the --crate-name option to rustc or by using the crate_nameattribute.
To link a crate to this new library you may use rustc's --extern flag. All of its items will then be imported under a module named the same as the library. This module generally behaves the same way as any other module.
>// extern crate rary; // May be required for Rust 2015 edition or earlier
>fn main() {
>rary::public_function();
>// Error! `private_function` is private
>//rary::private_function();
>rary::indirect_access();
>}
># Where library.rlib is the path to the compiled library, assumed that it's
># in the same directory here:
>$ rustc executable.rs --extern rary=library.rlib --edition=2018 && ./executable
>called rary's `public_function()`
>called rary's `indirect_access()`, that
>> called rary's `private_function()`
cargo is the official Rust package management tool. It has lots of really useful features to improve code quality and developer velocity! These include
• Dependency management and integration with crates.io (the official Rust package registry)
• Awareness of unit tests
• Awareness of benchmarks
This chapter will go through some quick basics, but you can find the comprehensive docs in The Cargo Book.
Most programs have dependencies on some libraries. If you have ever managed dependencies by hand, you know how much of a pain this can be. Luckily, the Rust ecosystem comes standard with cargo! cargo can manage dependencies for a project.
To create a new Rust project,
># A binary
>cargo new foo
># OR A library
>cargo new --lib foo
For the rest of this chapter, let's assume we are making a binary, rather than a library, but all of the concepts are the same.
After the above commands, you should see a file hierarchy like this:
>foo
>├── Cargo.toml
>└── src
>└── main.rs
The main.rs is the root source file for your new project -- nothing new there. The Cargo.toml is the config file for cargo for this project (foo). If you look inside it, you should see something like this:
>[package]
>name = "foo"
>version = "0.1.0"
>authors = ["mark"]
>[dependencies]
The name field under [package] determines the name of the project. This is used by crates.io if you publish the crate (more later). It is also the name of the output binary when you compile.
The version field is a crate version number using Semantic Versioning.
The authors field is a list of authors used when publishing the crate.
The [dependencies] section lets you add dependencies for your project.
For example, suppose that we want our program to have a great CLI. You can find lots of great packages on crates.io (the official Rust package registry). One popular choice is clap. As of this writing, the most recent published version of clap is 2.27.1. To add a dependency to our program, we can simply add the following to our Cargo.toml under [dependencies]: clap = "2.27.1". And that's it! You can start using clap in your program.