Skip to content

1. Toolchain and Cargo

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

Rust is installed with rustup on every OS. Rust uses the platform’s linker, so each OS also needs its native C build tools.

Terminal window
winget install Rustlang.Rustup

Or 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.

Then, on any OS:

Terminal window
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 stable
Terminal window
cargo new hello
cd hello
cargo 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!

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
Cargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2024"
[dependencies]
src/main.rs
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.
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
Terminal window
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 — like packages.lock.json or a Gradle lockfile. Commit it for applications.
  • Debug and release builds land in target/debug and target/release (like bin/Debug and bin/Release).
  • rustup manages compilers, cargo does 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 check for fast feedback, cargo build --release for optimized binaries.
  1. Create a project called dice, add the rand crate, and find in Cargo.lock which version was actually resolved.
Solution
Terminal window
cargo new dice
cd dice
cargo add rand
cargo build
Select-String -Path Cargo.lock -Pattern 'name = "rand"' -Context 0,1

Cargo.toml holds the requirement you asked for; Cargo.lock holds the exact version (and every transitive dependency) that was chosen.

  1. What is the difference between cargo check and cargo 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.