1. Toolchain and Cargo
The three tools
Section titled “The three tools”| Rust | Role | C# | Java |
|---|---|---|---|
rustup |
installs and updates toolchains | .NET SDK installer / global.json |
SDKMAN!, JDK installers |
cargo |
build, run, test, add dependencies | dotnet CLI |
Maven / Gradle |
| crates.io | public package registry | NuGet | Maven Central |
rustc |
the compiler (Cargo calls it for you) | Roslyn (csc) |
javac |
Installing
Section titled “Installing”Rust is installed with rustup on every OS. Rust uses the platform’s linker, so each OS also needs its native C build tools.
winget install Rustlang.RustupOr download rustup-init.exe from rustup.rs. The default toolchain targets MSVC, so you also need the Visual Studio C++ Build Tools (the linker); rustup-init offers to install them if they are missing. Open a new terminal afterwards so cargo is on the PATH.
sudo apt install build-essential # the C linker (Debian/Ubuntu; use your distro's package otherwise)curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. "$HOME/.cargo/env" # or open a new shellOn WSL, install Rust inside the Linux distribution, not through the Windows installer, and keep your projects in the Linux file system (~/src/...), not under /mnt/c: builds are much faster there. VS Code and RustRover can open a WSL folder directly.
xcode-select --install # the Apple command-line tools, which include the linkercurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. "$HOME/.cargo/env" # or open a new terminalThen, on any OS:
rustc --version # rustc 1.94.0 (4a4ef493e 2026-03-02)cargo --version # cargo 1.94.0 (85eff7c80 2026-01-15)rustup update # upgrade to the latest stableCreating a project
Section titled “Creating a project”cargo new hellocd hellocargo run Creating binary (application) `hello` package Compiling hello v0.1.0 (…\hello) Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.01s Running `target\debug\hello.exe`Hello, world! Creating binary (application) `hello` packagenote: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html Compiling hello v0.1.0 (…/hello) Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.55s Running `target/debug/hello`Hello, world! Creating binary (application) `hello` packagenote: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html Compiling hello v0.1.0 (…/hello) Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.89s Running `target/debug/hello`Hello, world!The Linux and macOS outputs come from the course’s CI runners, which use a newer Cargo that adds the note: line.
cargo new also runs git init and writes a .gitignore. The layout:
hello/├── Cargo.toml ← like .csproj or pom.xml├── src/│ └── main.rs ← entry point (a library would have src/lib.rs)└── .gitignore[package]name = "hello"version = "0.1.0"edition = "2024"
[dependencies]fn main() { println!("Hello, world!");}println!ends with!because it is a macro, not a function (it checks the format string at compile time).- The edition (
2024) is like<LangVersion>or--release: it opts into language changes without breaking older crates, which keep compiling with their own edition.
Everyday commands
Section titled “Everyday commands”| Task | Cargo | dotnet | Maven |
|---|---|---|---|
| New app | cargo new app |
dotnet new console |
mvn archetype:generate |
| New library | cargo new --lib lib |
dotnet new classlib |
— |
| Fast type-check | cargo check |
— | — |
| Build (debug) | cargo build |
dotnet build |
mvn compile |
| Build (release) | cargo build --release |
dotnet build -c Release |
mvn package |
| Run | cargo run |
dotnet run |
mvn exec:java |
| Test | cargo test |
dotnet test |
mvn test |
| Add dependency | cargo add rand |
dotnet add package |
edit pom.xml |
| Format | cargo fmt |
dotnet format |
Spotless plugin |
| Lint | cargo clippy |
Roslyn analyzers | Error Prone, SpotBugs |
| API docs | cargo doc --open |
XML docs + DocFX | javadoc |
Dependencies
Section titled “Dependencies”cargo add rand[dependencies]rand = "0.10.2""0.10.2"means compatible with 0.10.2 (SemVer caret), not “exactly 0.10.2”.- The exact resolved versions are written to
Cargo.lock— likepackages.lock.jsonor a Gradle lockfile. Commit it for applications. - Debug and release builds land in
target/debugandtarget/release(likebin/Debugandbin/Release).
Key takeaways
Section titled “Key takeaways”rustupmanages compilers,cargodoes everything else, crates.io hosts packages.- Each OS needs its native linker: Visual Studio Build Tools,
build-essential, or the Xcode command-line tools. Cargo.toml+Cargo.lock≈.csproj+ lockfile /pom.xml.cargo checkfor fast feedback,cargo build --releasefor optimized binaries.
Exercises
Section titled “Exercises”- Create a project called
dice, add therandcrate, and find inCargo.lockwhich version was actually resolved.
Solution
cargo new dicecd dicecargo add randcargo buildSelect-String -Path Cargo.lock -Pattern 'name = "rand"' -Context 0,1cargo new dicecd dicecargo add randcargo buildgrep -A1 'name = "rand"' Cargo.lockcargo new dicecd dicecargo add randcargo buildgrep -A1 'name = "rand"' Cargo.lockCargo.toml holds the requirement you asked for; Cargo.lock holds the exact version (and every transitive dependency) that was chosen.
- What is the difference between
cargo checkandcargo build, and when would you use each?
Solution
cargo check type-checks and borrow-checks without producing a binary, so it is fast — use it while editing. cargo build also generates machine code — use it when you need to run the program, and cargo build --release for an optimized version.