Development
Find out how to create and organize your content quickly and intuitively.
Find out how to create and organize your content quickly and intuitively.
git config --global user.name "spider_net" # username init, seen in commits
git config --global user.email "test@gmail.com" # Init of user e-mail
ΠΠ»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΠΎΠ΄Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ Ρ ΡΠ΅ΠΌ ΠΈ Π΄ΡΡΠ³ΠΈΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠ΅ΠΌ ΠΏΠΎ SSH Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠ»ΡΡΠΈ SSH ΠΏΠΎΠ΄ ΠΎΠ±Π°, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΎΠΏΠΈΡΠ°ΡΡ Π² ΡΠ°ΠΉΠ»Π΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΏΡΠΎΡΠΈΠ»ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ:
Host github.com
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes
Host gitlab.com
IdentityFile ~/.ssh/id_ecdsa
ΠΠ»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠ°Π±ΠΎΡΠΎΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ssh Π½Π°ΠΏΡΡΠΌΡΡ:
ssh -vvvv git@github.com
ΠΠ»Ρ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ ΡΠ»Π΅Π΄ΡΠ΅Ρ:
-
git clone
, Π΄Π°Π»Π΅Π΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ Π΅Π³ΠΎ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΈ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ git push origin main
git clone https://github.com/drupal/drupal.git drupal7
git init # local repo init
git status # check status
git branch -m master main # change master branch to main, for GitLab
git add * # add all files to repo, .gitignore file lets you hide junk files, password files from syncing
git commit -m "Hello world"
git config --global user.email "Ivan@example.com"
git config --global user.name "Ivan the Terrible"
git log
git remote add origin git@gitlab.com:<name of account>/<project name>.git
git push origin main
Certificate file needed in .ssh
folder. Also a config file .ssh/config is needed:
Host git-codecommit.us-east-1.amazonaws.com
User Your-SSH-Key-ID, such as APKAEIBAERJR2EXAMPLE
IdentityFile Your-Private-Key-File, such as ~/.ssh/codecommit_rsa or ~/.ssh/id_rsa
Git commands to clone repo:
git clone ssh://<SSHKEY-ID>@git-codecommit.<REGION>.amazonaws.com/v1/repos/<REPO-NAME>
# Example:
git clone ssh://ABCDOIJKHJGYTHJG7@git-codecommit.eu-central-1.amazonaws.com/v1/repos/myrepo
Create new branch: git branch new-branch
Pointer does not automatically switch to new branch, it is left on main branch, so you need to switch manually: git checkout new-branch
git commit
git checkout main
git commit
git merge new-branch
Change of branches to make it look as if the functionality was developed step-by-step, not in parallel.
git rebase master
git checkout master
git rebase bugFix
HEAD is the pointer to current project state. By default HEAD points to current branch.
You can go back by commits or by direct commit hash:
git checkout C1
You can use syntax “^K” for going up 1 level (where K is the route number to choose if there are more than 1 parent. By default, K=1) and “~N” for N steps up:
git checkout master^
# OR
git checkout bugFix^^
# OR
git checkout bugFix~2
# same route on schema from picture
# or build a sequence
git checkout bugFix^~1
Chaning main branch to several commits backwards:
git branch -f master HEAD~3
# -f means force - direct remap of branch for commit
For 1-person local repo do reset. For multi-person remote repo, do revert.
git reset HEAD~1
# OR
git revert HEAD
In c2’ state are the changes, which cancel state C2
Chosen commits are moved upon current commit using cherry-pick command. Used when it is known what specific commits to move: git cherry-pick C2 C4
git rebase -i HEAD~4 --aboveAll
You can modify a commit, dividing it into two with same parent:
git commit --amend
Marking milestones is done with tags. They block the commit from changes, moving etc.:
git tag v1 <hash> # if hash is not provided, then current commit is tagged
Tags serve as anchors in tree of commits. To define your position against the nearest anchor, use command:
git describe <ref> # if <ref> is not provided, current commit will be described
Remote branches have a naming convention: <remote name>/<branch name>
Main remote i called origin. So master branch is origin/main. When doing commit in local branch, the system is put into detached HEAD mode:
git checkout origin/master
git commit
When data is downloaded from remote repo, the origin/main branch is updated to reflect the new commits:
git fetch
Only commits non-present locally are downloaded. No local state of files is changed after download. The local main status is unchanged. To change, a merge must be done:
git fetch + git merge = git pull
git pull
Publishing syncs commits at remote repo and local repo (main and origin/main point to the same commit):
git push
If the remote repo has changed by someone by the time you need to push there, it means that your feature is based on an old commit. So Git will not let you push. Before push, a fetch must be made to sync the changes, than a rebase or merge to update the main branch, and then a push:
git fetch + git rebase origin/main + git push OR git fetch + git merge origin/main + git push = git pull –rebase
git pull --rebase
You can change that another branch will be main for the remote repo: `git checkout -b side origin/main
You can specify what branch to push:
git push origin main
origin = remote repo, main = branch to take commit from.
It does not matter where the HEAD is at this moment. You can specify where to push commits using git push origin <source>:<destination>
notation:
git push origin side^2:master
If push is made to a non-existent branch on remote repo, Git will create this branch:
git push origin main:newBranch
Same as push, but the other wat around. Go to foo branch on remote repo, download commits from there to local branch origin/foo:
git fetch origin foo
Cargo
Rust libraries
Command-line arguments
Closures and filters
Constant values
Cross-compiling of RUST code to different OS
Enums and match
Error handling in Rust
File reading in Rust
Rust program flow control - if-else, loops
Generics in Rust
Rust Hashmap collection
Rust modules cheat sheet
Rust ownership and reference rules
Rust regular expressions
Rust &String and &str difference
Rust struct type
Rust Threads
Rust traits
Rust variables
Rust vectors
ΠΠ»ΡΡΡ Rust:
ΠΠΈΠ½ΡΡΡ:
Golang, Ρ ΠΎΡΠΎΡΠΈΠΉ-ΠΏΠ»ΠΎΡ ΠΎΠΉ-Π·Π»ΠΎΠΉ: https://habr.com/ru/companies/vk/articles/353790/
External links:
rustup component add rustfmt
rustup component add rust-src
cargo install --locked bacon
#cargo install cargo-watch
brew install rust-analyzer
git clone https://github.com/AstroNvim/AstroNvim ~/.config/nvim
nvim +PackerSync
# After install use commands:
:LspInstall rust -> rust-analyzer
:TSInstall rust
git clone https://github.com/neovide/neovide
cd neovide
cargo build --release
cargo install evcxr_repl
cargo install irust
cargo install --locked bacon
bacon test # run from project folder
(For CodeLLDB) Allow breakpoints everywhere: "debug.allowBreakpointsEverywhere": true
cargo check: ΠΏΠΎΠΌΠ΅Π½ΡΡΡ check Π½Π° clippy: "rust-analyzer.check.command": "clippy"
Rust has a Prelude - a set of libraries included in every project. See current libs included in Prelude
Turn off noise about unused objects while learning with a crate attribute:
#![allow(unused)] // silence unused warnings while learning
fn main() {}
std::io::stdin library is used to get user input from standard input stream. Not included in Prelude:
use std:io
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("Failed to load");
.expect handles Err variant of read_line function, crashing the program with the defined error message.
Use Cargo for managing projects.
cargo new test_project // create project with binary file src/main.rs
// OR
cargo new test_project --lib // create project with library file src/lib.rs
cd test_project
Source code is in src folder.
cargo build # build project for debug, do not run
cargo run # build & run project
cargo check # fast compiling
cargo build --release # slow build with optimizations for speed of release version
Documentation of methods & traits used in code can be compiled an opened in browser with Cargo command:
cargo doc --open
Create “examples” folder beside the “src” folder. Create a file named, for example, “variables.rs” and place some test code in the folder. Then in the project root folder run:
cargo run --example variables
This will compile+build the code in examples folder, file “variables.rs”. Very convenient to try test different stuff. For live development do:
bacon run -- -q # ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΡΠ΅ΠΊΡΡΠΈΠΉ ΠΏΡΠΎΠ΅ΠΊΡ
bacon run -- -q --example <ΡΠ°ΠΉΠ»> # ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΡΠ°ΠΉΠ» Π² ΠΏΠ°ΠΏΠΊΠ΅ examples
-q - ΡΠ±ΡΠ°ΡΡ Π²ΡΠ²ΠΎΠ΄ Π΄Π΅ΡΠ°Π»Π΅ΠΉ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ
This will compile+build the code in examples folder, file “variables.rs”. Very convenient to try test different stuff. For live development do:
cargo watch -q -c -x 'run -q --example variables'
-x - rerun upon code change -c - clear terminal each time -q - quiet mode βΠΡΠΎΠ΅ΠΊΡ cargo watch Π·Π°ΠΌΠΎΡΠΎΠΆΠ΅Π½, Π±ΠΎΠ»Π΅Π΅ Π½Π΅ ΡΠ°Π·Π²ΠΈΠ²Π°Π΅ΡΡΡ.
Π ΠΎΡΠ²Π΅Ρ Π½Π° ΠΏΠ°Π½ΠΈΠΊΡ, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠ°Π·ΠΌΠ°ΡΡΠ²Π°Π΅Ρ ΡΡΠ΅ΠΊ (unwinding) - ΠΏΡΠΎΡ
ΠΎΠ΄ΠΈΡ ΠΏΠΎ ΡΡΠ΅ΠΊΡ ΠΈ Π²ΡΡΠΈΡΠ°Π΅Ρ Π΄Π°Π½Π½ΡΠ΅ Π²ΡΠ΅Ρ
ΡΡΠ½ΠΊΡΠΈΠΉ. ΠΠ»Ρ ΡΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΡ ΡΠ°Π·ΠΌΠ΅ΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΠΎΡΠΊΠ»ΡΡΠ°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π±Π΅Π· ΠΎΡΠΈΡΡΠΊΠΈ - abort. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π² ΡΠ°ΠΉΠ»Π΅ Cargo.toml Π½Π°Π΄ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² ΡΠ°Π·Π΄Π΅Π»Ρ [profile]
:
[profile.release]
panic = 'abort'
Example of Clippy config:
cargo clippy --fix -- \
-W clippy::pedantic \
-W clippy::nursery \
-W clippy::unwrap_used \
-W clippy::expect_used
Clippy has a markdown book:
cargo install mdbook
# Run from top level of your rust-clippy directory:
mdbook serve book --open
# Goto http://localhost:3000 to see the book
ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°ΡΠ°ΡΡ Π²ΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ Cargo Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΡΠΎΠ΅ΠΊΡΠ° Panamax.
cargo install --locked panamax
panamax init ~/test/my-mirror
ΠΡΠΆΠ½ΠΎ Π·Π°ΠΉΡΠΈ Π² ΠΏΠ°ΠΏΠΊΡ my-mirror, ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π² ΡΠ°ΠΉΠ»Π΅ mirror.toml. Π Π΄Π°Π»Π΅Π΅ Π·Π°ΠΏΡΡΡΠΈΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ:
panamax sync ~/test/my-mirror
ΠΠ°Π»Π΅Π΅, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°ΡΡ Π·Π΅ΡΠΊΠ°Π»ΠΎ ΠΏΠΎ Π²Π΅Π± ΡΠ΅ΡΠ΅Π· Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ (ΠΏΠΎ ΠΏΠΎΡΡΡ 8080):
panamax serve ~/test/my-mirror
ΠΠ° ΠΈΠ½Π΄Π΅ΠΊΡ ΡΡΡΠ°Π½ΠΈΡΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠ° Π±ΡΠ΄Π΅Ρ ΡΠΏΡΠ°Π²ΠΊΠ° ΠΏΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Rust ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ² ΠΊ Π·Π΅ΡΠΊΠ°Π»Ρ. Π ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠ°ΠΉΠ»Π° Π½Π°ΡΡΡΠΎΠ΅ΠΊ ~/.cargo/config :
[source.my-mirror]
registry = "http://panamax.local/crates.io-index"
[source.crates-io]
replace-with = "my-mirror"
ΠΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° Π² 1 ΠΏΡΠΎΠ΅ΠΊΡ. Π Cargo.toml Π½ΡΠΆΠ½ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΡΡ Π΅Π³ΠΎ ΡΡΡΡΠΊΡΡΡΡ:
[package]
name = "ardan_workspace"
version = "0.1.0"
edition = "2021"
[dependencies]
[workspace]
members = [
"session1/hello_world",
"session1/variables",
]
ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΏΠΎΠ΄ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² members, ΡΠ΅ΡΠ΅Π· cargo new <ΠΏΠΎΠ΄ΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°>
.
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π²ΠΌΠ΅ΡΡΠΎ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊΠ° - `cargo new –lib examplelib
ΠΡΠΎΠΏΠΈΡΠ°ΡΡ Π² ΡΠ°ΠΉΠ»Π΅ cargo.toml Ρ Π±ΠΈΠ½Π°ΡΠ½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² workspace Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡ:
<..>
[dependencies]
examplelib = { path = "../examplelib"}
ΠΠ°Π»Π΅Π΅, Π² ΠΊΠΎΠ΄ Π±ΠΈΠ½Π°ΡΠ½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π²ΠΊΠ»ΡΡΠΈΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ:
use examplelib::function01; // ΡΡΠΊΠ½ΠΊΡΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎΠΉ (pub fn)
Anyhow error-handling library
Clap CLI library
CLI Stdin / Stderr commands
Itertools library
Random numbers library
Regular Expressions library
Serialization / Deserialization Library
System Information Library
Observability in Rust with Tokio tracing lib and OpenTelemetry
ΠΡΠΈΠΌΠ΅ΡΡ:
pub fn greet_user(name: &str) -> String {
format!("Hello {name}")
}
pub fn login(username: &str, password: &str) -> bool {
username == "admin" && password == "P@ssw0rd"
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_greet_user() {
assert_eq!("Hello Alex", greet_user("Alex"));
}
#[test]
fn test_login() {
assert!(login("admin", "P@ssw0rd"));
}
}
ΠΠ°ΠΏΡΡΠΊ ΡΠ΅ΡΡΠΎΠ² - ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ cargo test
ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΡΠ°Π±ΠΎΡΡ Ρ ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ - https://docs.rs/anyhow/latest/anyhow/
cargo add anyhow
Anyhow ΡΠΎΠ·Π΄Π°ΡΡ Π°Π»ΠΈΠ°Ρ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Result<T> = Result<T, Box<dyn Error>>
, ΡΡΠΎΠ±Ρ ΡΠΊΡΡΡΡ ΡΠΈΠΏ ΠΎΡΠΈΠ±ΠΎΠΊ ΠΈ ΡΠ΄Π΅Π»Π°ΡΡ Π΅Π³ΠΎ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΡΠΌ.
// ---- ΠΠ΅Π· Anyhow
fn string_error() -> Result<(), String> {
Ok(())
}
fn io_error() -> Result<(), std::io::Error> {
Ok(())
}
fn any_error() -> Result<(), Box<dyn Error>> {
string_error()?;
io_error()?;
Ok(())
}
// ---- Π‘ Anyhow:
use anyhow::Result;
fn string_error() -> Result<()> {
Ok(())
}
fn io_error() -> Result<()> {
Ok(())
}
fn any_error() -> Result<()> {
string_error()?;
io_error()?;
Ok(())
}
ΠΡΠΈΠΌΠ΅Ρ Π½Π΅ΡΠ΄Π°ΡΠ½ΠΎΠ³ΠΎ ΡΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°:
use anyhow::{Context, Result};
fn read_config_file(path: &str) -> Result<String> {
std::fs::read_to_string(path).with_context(|| format!("Failed to read file {}", path))
}
fn main() -> Result<()> {
let config_content = read_config_file("conf.txt")?;
println!("Config content:\n{:?}", config_content);
Ok(())
}
Result<T>
ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π°Π»ΠΈΠ°ΡΠΎΠΌ ΠΊ Result<T, anyhow::Error>
;Context
, with_context()
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ ΠΊ ΠΎΡΠΈΠ±ΠΊΠ΅, Π² ΡΠ»ΡΡΠ°Π΅ Π½Π΅ΡΡΠΏΠ΅Ρ
Π° ΡΡΠ½ΠΊΡΠΈΠΈ ΡΡΠ΅Π½ΠΈΡ read_to_string()
;?
Π²ΡΠ½ΠΎΡΠΈΡ ΠΎΡΠΈΠ±ΠΊΡ Π²Π²Π΅ΡΡ
, ΠΏΡΠΈ ΡΡΠΎΠΌ Π°Π²ΡΠΎ-ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅Ρ Π΅Ρ ΡΠΈΠΏ Π² anyhow::Error
.Box<dyn>
Ρ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΠΌΠΠΎΠ·ΡΠΌΡΠΌ ΠΏΡΠΈΠΌΠ΅Ρ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° std::fs::read_to_string()
(ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅ΡΠ΄Π°ΡΠ½ΡΠΌ), Π΄Π°Π»Π΅Π΅ Π΄Π΅ΡΠΈΡΡΠΎΠ²ΠΊΠ° Π΅Π³ΠΎ ΠΊΠΎΠ½ΡΠ΅Π½ΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ base64 decode()
(ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡΡ) Π² ΡΠ΅ΠΏΠΎΡΠΊΡ Π±Π°ΠΉΡ, ΠΈΠ· ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠΎΡΠΌΠΈΡΡΠ΅ΡΡΡ ΡΡΡΠΎΠΊΠ° String::from_utf8()
(ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡΡ). ΠΡΠ΅ ΡΡΠΈ ΡΡΠΈ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ
ΠΎΡΠΈΠ±ΠΊΠΈ ΠΈΠΌΠ΅ΡΡ ΡΠ°Π·Π½ΡΠΉ ΡΠΈΠΏ.
ΠΠ΄ΠΈΠ½ ΡΠΏΠΎΡΠΎΠ± Π²ΡΠ΅ ΡΡΠΈ ΠΈΡ
ΠΏΡΠΈΠ½ΡΡΡ Π½Π° ΠΎΠ΄Π½Ρ ΡΡΠ½ΠΊΡΠΈΡ, ΡΡΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Box<dyn std::error::Error>>
, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π²ΡΠ΅ 3 ΠΎΡΠΈΠ±ΠΊΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ std::error::Error
.
use base64::{self, engine, Engine};
fn decode() -> Result<(), Box<dyn std::error::Error>> {
let input = std::fs::read_to_string("input")?;
for line in input.lines() {
let bytes = engine::general_purpose::STANDARD.decode(line)?;
println!("{}", String::from_utf8(bytes)?);
}
Ok(())
}
ΠΠΎΠ΄Ρ ΠΎΠ΄ ΡΠ°Π±ΠΎΡΠΈΠΉ, Π½ΠΎ ΠΏΡΠΈ ΡΡΠ°Π±Π°ΡΡΠ²Π°Π½ΠΈΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· ΡΡΡΡ ΠΎΡΠΈΠ±ΠΎΠΊ, ΡΡΠ΄ΠΈΡΡ ΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ Π»ΠΈΡΡ ΠΏΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π²Π½ΡΡΡΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ.
Π ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ Anyhow, ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΈΠΌ Box<dyn>
, ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΡΠ°Π·Ρ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ½ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠ½ΡΡΡ ΠΌΠ΅ΡΡΠΎ:
use anyhow::Context;
use base64::{self, engine, Engine};
fn decode() -> Result<(), anyhow::Error> {
let input = std::fs::read_to_string("input")
.context("Failed to read file")?; // ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ 1
for line in input.lines() {
let bytes = engine::general_purpose::STANDARD
.decode(line)
.context("Failed to decode the input")?; // ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ 2
println!(
"{}",
String::from_utf8(bytes)
.context("Failed to cenvert bytes")? // ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ 3
);
}
Ok(())
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π²ΠΌΠ΅ΡΡΠ΅ Ρ Π΄ΠΎΠΏΠΎΠΌ derive, ΡΡΠΎΠ±Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ clap ΠΊΠ°ΠΊ ΠΏΡΠΈΠ·Π½Π°ΠΊ (trait) Ρ ΡΡΡΡΠΊΡΡΡ Π΄Π°Π½Π½ΡΡ .
cargo add clap -F derive
ΠΠΎΠ±Π°Π²ΠΊΠ° clap ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠ°ΡΡΠΈΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ, Π° ΡΠ°ΠΊΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΠΊΠ»ΡΡΠΈ “-h” ΠΈ “–help” Π΄Π»Ρ ΠΏΠΎΠΌΠΎΡΠΈ Π±Π΅Π· ΠΊΠΎΠ΄Π°:
use clap::Parser;
#[derive(Parser, Debug)]
struct Args {
arg1: String,
arg2: usize,
}
fn main() {
let args = Args::parse();
println!("{:?}", args)
}
ΠΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ Π΄Π°Π½Π½Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΡΠ΅Π±ΡΠ΅Ρ 2 Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°, ΠΏΡΠΈΡΠΎΠΌ Π²ΡΠΎΡΠΎΠΉ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠΈΡΠ»ΠΎΠΌ.
ΠΠΌΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈ Π²Π΅ΡΡΠΈΡ Π²Π½ΠΎΡΡΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌ ΠΏΡΠΈΠ·Π½Π°ΠΊΠΎΠΌ. ΠΠΎΠΏ. ΠΏΠΎΠ»Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ Π²Π½ΠΎΡΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΏΠ΅Ρ. ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠ΅Π² ///
:
use clap::Parser;
#[derive(Parser, Debug)]
#[command(author = "Author Name", version, about)]
/// A very simple CLI parser
struct Args {
/// Text argument option
arg1: String,
/// Number argument option
arg2: usize,
}
fn main() {
let args = Args::parse();
println!("{:?}", args)
}
Π€Π»Π°Π³ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π°Π½Π½ΠΎΡΠ°ΡΠΈΠΈ #[arg(short, long)]
Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΊΠΎΠ³ΠΎ ΠΈ Π΄Π»ΠΈΠ½Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΡ ΡΠ»Π°Π³Π°. ΠΡΠ»ΠΈ Ρ 2-Ρ
ΡΠ»Π°Π³ΠΎΠ² ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Π°Ρ ΠΏΠ΅ΡΠ²Π°Ρ Π±ΡΠΊΠ²Π°, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π²ΡΡΡΠ½ΡΡ ΠΈΡ
ΠΊΠΎΡΠΎΡΠΊΡΡ Π²Π΅ΡΡΠΈΡ. ΠΠΎΡΠΎΡΠΊΠ°Ρ Π²Π΅ΡΡΠΈΡ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ String, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ 1 char.
<..>
struct Args {
#[arg(short = 'a', long)]
/// Text argument option
arg1: String,
#[arg(short = 'A', long)]
/// Number argument option
arg2: usize,
}
<..>
ΠΠ»Ρ ΠΎΡΠΌΠ΅ΡΠΊΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° ΠΊΠ°ΠΊ Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π΅Π³ΠΎ ΡΠΈΠΏ ΠΊΠ°ΠΊ Option<ΡΠΈΠΏ>
ΠΈ Π² ΡΠΊΠΎΠ±ΠΊΠ°Ρ
ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ
:
struct Args {
#[arg(short = 'a', long)]
/// Text argument option
arg1: String,
#[arg(short = 'A', long)]
/// Number argument option
arg2: Option<usize>,
}
Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ ΡΠΈΡΡΠ°ΡΠΈΡ, ΠΊΠΎΠ³Π΄Π° Π² arg2 Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅Ρ. ΠΠΌΠ΅ΡΡΠΎ ΡΠ°ΠΊ Π΄Π΅Π»Π°ΡΡ, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ:
struct Args {
#[arg(short = 'a', long)]
/// Text argument option
arg1: String,
#[arg(default_value_t=usize::MAX, short = 'A', long)]
/// Number argument option
arg2: usize,
}
Π’Π΅ΠΏΠ΅ΡΡ arg2 ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π±ΡΠ΄Π΅Ρ ΡΠ°Π²Π΅Π½ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΌΡ ΡΠΈΡΠ»Ρ usize
, Π΅ΡΠ»ΠΈ Π½Π΅ ΡΠΊΠ°Π·Π°Π½ΠΎ ΠΈΠ½ΠΎΠ΅.
Π ΡΠ»ΡΡΠ°Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°-ΡΡΡΠΎΠΊΠΈ Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π²Π²Π΅ΡΡΠΈ ΠΏΡΡΡΡΡ ΡΡΡΠΎΠΊΡ ΠΈΠ· ΠΏΡΠΎΠ±Π΅Π»ΠΎΠ² " "
. ΠΠ»Ρ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠ°ΠΊΠΈΡ
Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ², Π²Π²ΠΎΠ΄ΠΈΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ ΠΈ Π΅Ρ Π²ΡΠ·ΠΎΠ²:
use clap::Parser;
#[derive(Parser, Debug)]
#[command(author = "Author Name", version, about)]
/// A very simple CLI parser
struct Args {
#[arg(value_parser = validate_argument_name, short = 'a', long)]
/// Text argument option
arg1: String,
#[arg(default_value_t=usize::MAX, short = 'A', long)]
/// Number argument option
arg2: usize,
}
fn validate_argument_name(name: &str) -> Result<String, String> {
if name.trim().len() != name.len() {
Err(String::from(
"ΡΡΡΠΎΠΊΠ° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° Π½Π°ΡΠΈΠ½Π°ΡΡΡΡ ΠΈΠ»ΠΈ Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°ΡΡΡΡ ΠΏΡΠΎΠ±Π΅Π»Π°ΠΌΠΈ",
))
} else {
Ok(name.to_string())
}
}
fn main() {
let args = Args::parse();
println!("{:?}", args)
}
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΡΠΈ ΠΏΠΎΠΏΡΡΠΊΠ΅ Π²ΡΠ·Π²Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ tiny-clapper -- -a " "
Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΠΎΡΠΈΠ±ΠΊΠ° Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ.
ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π² ΠΠ‘.
spawn
β runs the program and returns a value with detailsoutput
β runs the program and returns the outputstatus
β runs the program and returns the exit code let output = Command::new("cat")
.arg("/etc/issue")
.output()
.with_context(|| "ls command failed")?;
println!("{}", output.status);
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("{}", String::from_utf8_lossy(&output.stderr));
βΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ - ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ, Π½Π΅Π»ΡΠ·Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΠ²ΠΎΠΉ ΡΠ΅ΠΊΡΡ.
Π‘Π°ΠΌΡΠΉ Π³ΠΈΠ±ΠΊΠΈΠΉ Π²Π°ΡΠΈΠ°Π½Ρ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ Π΄Π΅Π»Π°ΡΡ ΡΠ²ΠΎΠΉ Π²Π²ΠΎΠ΄, Π° Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΈ ΡΠ°ΠΉΠ»Ρ-ΠΏΠ°ΠΏΠΊΠΈ, ΡΡΠΎ ΡΠ΅ΡΠ΅Π· spawn
:
let mut child = Command::new("cat") // ΠΊΠΎΠΌΠ°Π½Π΄Π°
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let stdin = child.stdin.as_mut()?;
stdin.write_all(b"Hello Rust!\n")?; // ΡΠ΅ΠΊΡΡ ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Π΅, /n ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»Π΅Π½
let output = child.wait_with_output()?;
for i in output.stdout.iter() { // ΡΠΈΠΊΠ» Π½Π° ΡΠ»ΡΡΠ°ΠΉ ΠΌΠ½ΠΎΠ³ΠΎΡΡΡΠΎΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π°
print!("{}", *i as char);
}
Ok(())
βΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ - ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π°Π²Π°ΡΡ Π½Π° Π²Ρ
ΠΎΠ΄ ΡΠ΅ΠΊΡΡ Π»ΠΈΡΡ ΡΠ΅ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΠ΅Π±ΡΡΡ ΡΡΠ°Π·Ρ ΡΠΊΠ°Π·Π°ΡΡ Π²Π²ΠΎΠ΄Π½ΡΠΉ ΡΠ΅ΠΊΡΡ. ΠΡΠΈ ΡΡΠΎΠΌ ΡΡΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄ Π΄Π΅Π»Π°ΡΡ ΠΏΠ°ΡΠ·Ρ ΠΏΠ΅ΡΠ΅Π΄ ΠΏΠΎΡΡΠ΅Π±Π»Π΅Π½ΠΈΠ΅ΠΌ ΡΠ΅ΠΊΡΡΠ° Π½Π° Π²Ρ
ΠΎΠ΄, Ρ ΡΠ°ΠΊΠΈΠΌΠΈ ΡΠ²ΠΎΠΉ Π²Π²ΠΎΠ΄ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΡΠΎ ΠΎΡΠ½ΠΎΡΠΈΡΡΡ ΠΈ ΠΊ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ ΡΠ΅ΡΠ΅Π· pipe = | grep <...>
ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈ.
https://doc.rust-lang.org/std/pipe/fn.pipe.html ΠΠ»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π½ΡΠΆΠ΅Π½ nightly Π²Π°ΡΠΈΠ°Π½Ρ Rust
rustup install nightly
rustup default nightly
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅:
#![feature(anonymous_pipe)] // ΡΠΎΠ»ΡΠΊΠΎ Π² Rust Nightly
use std::pipe
let text = "| grep file".as_bytes();
// ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΡΠ°ΠΌΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ
let child = Command::new("ls")
.arg("/Users/test")
.stdin({
// ΠΠ΅Π»ΡΠ·Ρ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ ΠΏΡΠΎΡΡΠΎ ΡΡΡΠΎΠΊΡ Π² ΠΊΠΎΠΌΠ°Π½Π΄Ρ
// ΠΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΠΉ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ (ΠΊΠ°ΠΊ Π² ΠΎΠ±ΡΡΠ½ΠΎΠΌ stdin "pipe")
// ΠΠΎΡΡΠΎΠΌΡ ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΏΠ°ΡΡ pipes ΡΡΡ
let (reader, mut writer) = std::pipe::pipe().unwrap();
// ΠΠΈΡΠ΅ΠΌ ΡΡΡΠΎΠΊΡ Π² ΠΎΠ΄Π½Ρ pipe
writer.write_all(text).unwrap();
// Π΄Π°Π»Π΅Π΅ ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Π΅ΠΌ Π²ΡΠΎΡΡΡ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π² ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΡΠ°Π·Ρ ΠΏΡΠΈ spawn.
Stdio::from(reader)
})
.spawn()?;
External link: https://docs.rs/itertools/latest/itertools/
use itertools::Itertools;
let text = "Hello world";
let text_sorted = text.chars().sorted().rev().collect::<String>();
// rev() - Iterate the iterable in reverse
println!("Text: {}, Sorted Text: {}", text, text_sorted);
// Text: Hello world, Sorted Text: wroollledH
use itertools::Itertools;
let number_list = [1,12,3,1,5,2,7,8,7,8,2,3,12,7,7];
let mode = number_list.iter().counts(); // Itertools::counts()
// Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Hashmap, Π³Π΄Π΅ ΠΊΠ»ΡΡΠΈ Π²Π·ΡΡΡ ΠΈΠ· ΠΌΠ°ΡΡΠΈΠ²Π°, Π·Π½Π°ΡΠ΅Π½ΠΈΡ - ΡΠ°ΡΡΠΎΡΠ°
for (key, value) in &mode {
println!("Π§ΠΈΡΠ»ΠΎ {key} Π²ΡΡΡΠ΅ΡΠ°Π΅ΡΡΡ {value} ΡΠ°Π·");
}
External links:
Using rand lib example:
use rand::Rng;
fn main() {
let secret_of_type = rand::rng().random::<u32>();
let secret = rand::rng().random_range(1..=100);
println!("Random nuber of type u32: {secret_of_type}");
println!("Random nuber from 1 to 100: {}", secret); }
Π ΡΡΠ°ΡΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ»ΡΡ ΠΏΡΠΈΠ·Π½Π°ΠΊ gen(), ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠ΅ΡΠ΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π»ΠΈ Π² ΡΠ²ΡΠ·ΠΈ Ρ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ gen() Π² Rust 2024.
ΠΠ½Π΅ΡΠ½ΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ:
cargo add regex
. any character except new line (includes new line with s flag)
\d digit (\p{Nd})
\D not digit
\pX Unicode character class identified by a one-letter name
\p{Greek} Unicode character class (general category or script)
\PX Negated Unicode character class identified by a one-letter name
\P{Greek} negated Unicode character class (general category or script)
[xyz] A character class matching either x, y or z (union).
[^xyz] A character class matching any character except x, y and z.
[a-z] A character class matching any character in range a-z.
[[:alpha:]] ASCII character class ([A-Za-z])
[[:^alpha:]] Negated ASCII character class ([^A-Za-z])
[x[^xyz]] Nested/grouping character class (matching any character except y and z)
[a-y&&xyz] Intersection (matching x or y)
[0-9&&[^4]] Subtraction using intersection and negation (matching 0-9 except 4)
[0-9--4] Direct subtraction (matching 0-9 except 4)
[a-g~~b-h] Symmetric difference (matching `a` and `h` only)
[\[\]] Escaping in character classes (matching [ or ])
xy concatenation (x followed by y)
x|y alternation (x or y, prefer x)
x* zero or more of x (greedy)
x+ one or more of x (greedy)
x? zero or one of x (greedy)
x*? zero or more of x (ungreedy/lazy)
x+? one or more of x (ungreedy/lazy)
x?? zero or one of x (ungreedy/lazy)
x{n,m} at least n x and at most m x (greedy)
x{n,} at least n x (greedy)
x{n} exactly n x
x{n,m}? at least n x and at most m x (ungreedy/lazy)
x{n,}? at least n x (ungreedy/lazy)
x{n}? exactly n x
^ the beginning of text (or start-of-line with multi-line mode)
$ the end of text (or end-of-line with multi-line mode)
\A only the beginning of text (even with multi-line mode enabled)
\z only the end of text (even with multi-line mode enabled)
\b a Unicode word boundary (\w on one side and \W, \A, or \z on other)
\B not a Unicode word boundary
(exp) numbered capture group (indexed by opening parenthesis)
(?P<name>exp) named (also numbered) capture group (names must be alpha-numeric)
(?<name>exp) named (also numbered) capture group (names must be alpha-numeric)
(?:exp) non-capturing group
(?flags) set flags within current group
(?flags:exp) set flags for exp (non-capturing)
\* literal *, works for any punctuation character: \.+*?()|[]{}^$
\a bell (\x07)
\f form feed (\x0C)
\t horizontal tab
\n new line
\r carriage return
\v vertical tab (\x0B)
\123 octal character code (up to three digits) (when enabled)
\x7F hex character code (exactly two digits)
\x{10FFFF} any hex character code corresponding to a Unicode code point
\u007F hex character code (exactly four digits)
\u{7F} any hex character code corresponding to a Unicode code point
\U0000007F hex character code (exactly eight digits)
\U{7F} any hex character code corresponding to a Unicode code point
[[:alnum:]] alphanumeric ([0-9A-Za-z])
[[:alpha:]] alphabetic ([A-Za-z])
[[:ascii:]] ASCII ([\x00-\x7F])
[[:blank:]] blank ([\t ])
[[:cntrl:]] control ([\x00-\x1F\x7F])
[[:digit:]] digits ([0-9])
[[:graph:]] graphical ([!-~])
[[:lower:]] lower case ([a-z])
[[:print:]] printable ([ -~])
[[:punct:]] punctuation ([!-/:-@\[-`{-~])
[[:space:]] whitespace ([\t\n\v\f\r ])
[[:upper:]] upper case ([A-Z])
[[:word:]] word characters ([0-9A-Za-z_])
[[:xdigit:]] hex digit ([0-9A-Fa-f])
use regex::Regex;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let input = "hello, world!";
let pattern = Regex::new(r"hello, (world|universe)!")?;
let is_match = pattern.is_match(input);
println!("Is match: {}", is_match); // true
Ok(())
}
ΠΠ»Ρ ΠΏΡΠΎΡΡΠΎΠ³ΠΎ Π²ΡΡΡΠ½Π΅Π½ΠΈΡ ΡΠ°ΠΊΡΠ° ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΡ Π»ΡΡΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ is_match
ΠΊΠ°ΠΊ ΡΠ°ΠΌΡΠΌ Π±ΡΡΡΡΡΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ.
let pattern = regex::Regex::new(r"hello, (world|universe)!")?;
let input = "hello, world!";
let first_match = pattern.find(input);
println!("First match: {}", first_match.unwrap().as_str());
ΠΠ΅ΡΠ²ΠΎΠ΅ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ Π±ΡΠ΄Π΅Ρ ΠΈΠΌΠ΅ΡΡ ΡΠΈΠΏ Option<match>
, Π° Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΡΡΡΡΡΠ²ΠΈΡ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠΉ = None
.
let pattern = regex::Regex::new(r"hello, (world|universe)!")?;
let input = "hello, world! hello, universe!";
let matches: Vec<_> = pattern.find_iter(input).collect(); // find_iter()
matches.iter().for_each(|i| println!("{}", i.as_str()));
// matches = Vec<match> ΠΈ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π²ΡΠ΅ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΡ
Add serde framework with Derive feature to use it in structures and functions. Also add a separate serde_json lib for converting into specifically JSON:
cargo add serde -F derive
cargo add serde_json
Add serde, then mark the structures with Serialise, Deserialise traits and use serde_json for serialising:
use serde::{Deserialize, Serialize};
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
pub enum LoginRole {
Admin,
User,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub username: String,
pub password: String,
pub role: LoginRole,
}
pub fn get_default_users() -> HashMap<String, User> {
let mut users = HashMap::new();
users.insert(
"admin".to_string(),
User::new("admin", "password", LoginRole::Admin),
);
users.insert(
"bob".to_string(),
User::new("bob", "password", LoginRole::User),
);
users
}
pub fn get_users() -> HashMap<String, User> {
let users_path = Path::new("users.json");
if users_path.exists() {
// Load the file!
let users_json = std::fs::read_to_string(users_path).unwrap();
let users: HashMap<String, User> = serde_json::from_str(&users_json).unwrap();
users
} else {
// Create a file and return it
let users = get_default_users();
let users_json = serde_json::to_string(&users).unwrap();
std::fs::write(users_path, users_json).unwrap();
users
}
ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΄Π»Ρ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΡΠΈΡΡΠ΅ΠΌΡ ΠΈ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ ΡΠ΅ΡΡΡΡΠΎΠ². https://docs.rs/sysinfo/latest/sysinfo/
cargo add sysinfo
use sysinfo::{RefreshKind, System};
fn main() {
let _sys = System::new_with_specifics(RefreshKind::nothing());
println!("System name: {:?}", System::name());
println!("System kernel version: {:?}", System::kernel_version());
println!("System OS version: {:?}", System::os_version());
println!("System host name: {:?}", System::host_name());
}
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ RefreshKind::nothing()
ΠΎΡΠΊΠ»ΡΡΠ°ΡΡΡΡ Π²ΡΠ΅ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π²Π΅ΡΠΈ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΎΡΡΠ°ΡΠΎΠΊ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ, Π·Π°Π³ΡΡΠ·ΠΊΠ° Π¦ΠΠ£, ΡΠ΅ΡΡ ΠΈ ΡΠ°ΠΊ Π΄Π°Π»Π΅Π΅, ΡΡΠΎ Π΄ΡΠ°ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠΊΠΎΡΡΠ΅Ρ ΠΎΠΏΡΠΎΡ ΡΠΈΡΡΠ΅ΠΌΡ.
ΠΠΎΠΆΠ½ΠΎ ΡΠ°ΡΡΠΈΡΠ½ΠΎ ΠΎΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ ΡΠ°Π·Π½ΡΠ΅ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ ΡΠ΅ΡΡΡΡΡ, ΠΏΠΎ Π·Π°Π΄Π°Π½Π½ΡΠΌ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π°ΠΌ.
ΠΠ½Π΅ΡΠ½ΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ:
ΠΠ°Π±Π»ΡΠ΄Π°Π΅ΠΌΠΎΡΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠΎΠ½ΡΡΡ ΡΠΈΡΡΠ΅ΠΌΡ ΠΈΠ·Π²Π½Π΅, Π·Π°Π΄Π°Π²Π°Ρ Π²ΠΎΠΏΡΠΎΡΡ ΠΎ Π½Π΅ΠΉ, ΠΏΡΠΈ ΡΡΠΎΠΌ Π½Π΅ Π·Π½Π°Ρ Π΅Π΅ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π³ΠΎ ΡΡΡΡΠΎΠΉΡΡΠ²Π°. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΠΎΠ½Π° ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π»Π΅Π³ΠΊΠΎ ΡΡΡΡΠ°Π½ΡΡΡ Π½Π΅ΠΏΠΎΠ»Π°Π΄ΠΊΠΈ ΠΈ ΡΠ΅ΡΠ°ΡΡ Π½ΠΎΠ²ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, ΡΠΎ Π΅ΡΡΡ Β«Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅ Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅Β». ΠΠ½Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π²Π°ΠΌ ΠΎΡΠ²Π΅ΡΠΈΡΡ Π½Π° Π²ΠΎΠΏΡΠΎΡ Β«ΠΏΠΎΡΠ΅ΠΌΡ ΡΡΠΎ-ΡΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ?Β».
Π§ΡΠΎΠ±Ρ Π·Π°Π΄Π°ΡΡ ΡΡΠΈ Π²ΠΎΠΏΡΠΎΡΡ ΠΎ Π²Π°ΡΠ΅ΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅, ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΠΏΠΎΠ»Π½ΡΠΉ Π½Π°Π±ΠΎΡ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ². Π’ΠΎ Π΅ΡΡΡ ΠΊΠΎΠ΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡ ΡΠΈΠ³Π½Π°Π»Ρ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠΈ, ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΠΈ ΠΆΡΡΠ½Π°Π»Ρ. ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ Π½Π΅ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΡ Π΄Π»Ρ ΡΡΡΡΠ°Π½Π΅Π½ΠΈΡ Π½Π΅ΠΏΠΎΠ»Π°Π΄ΠΎΠΊ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Ρ Π½ΠΈΡ Π΅ΡΡΡ Π²ΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ°Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ.
cargo add tracing
cargo add tracing-subscriber -F json
ΠΡΠΎΡΡΠ°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΈ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΡΠΎΠ±ΡΡΠΈΠΉ:
use tracing::info;
fn main() {
// Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ±ΠΎΡΡΠΈΠΊΠ° ΠΏΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
tracing_subscriber::fmt::init();
let number_of_yaks = 3;
// Π½ΠΎΠ²ΠΎΠ΅ ΡΠΎΠ±ΡΡΠΈΠ΅, Π²Π½Π΅ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠΎΠ²
info!(number_of_yaks, "preparing to shave yaks");
}
Π ΡΡΠ½Π°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠ²ΠΎΠΉΡΡΠ² ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ° Π΄Π»Ρ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π»ΠΎΠ³Π°:
fn setup_tracing() {
let subscriber = tracing_subscriber::fmt()
.json() // Π½ΡΠΆΠ½ΠΎ cargo add tracing-subscriber -F json
.with_max_level(tracing::Level::TRACE) // ΠΠΠ₯ ΡΡΠΎΠ²Π΅Π½Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ
.compact() // ΠΊΠΎΠΌΠΏΠ°ΠΊΡΠ½ΡΠΉ Π»ΠΎΠ³
.with_file(true) // ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ ΡΠ°ΠΉΠ»-ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊ
.with_line_number(true) // ΠΏΠΎΠΊΠ°Π·Π°ΡΡ Π½ΠΎΠΌΠ΅ΡΠ° ΡΡΡΠΎΠΊ ΠΊΠΎΠ΄Π°
.with_thread_ids(true) // ΠΏΠΎΠΊΠ°Π·Π°ΡΡ ID ΠΏΠΎΡΠΎΠΊΠ° Ρ ΡΠΎΠ±ΡΡΠΈΠ΅ΠΌ
.with_target(false) // Π½Π΅ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ ΡΠ΅Π»Ρ (ΠΌΠΎΠ΄ΡΠ»Ρ) ΡΠΎΠ±ΡΡΠΈΡ
.finish();
tracing::subscriber::set_global_default(subscriber).unwrap();
tracing::info!("Starting up");
tracing::warn!("Are you sure this is a good idea?");
tracing::error!("This is an error!");
}
use tracing::{instrument, warn};
#[instrument]
fn sync_tracing() {
warn!("event 1");
sync_tracing_sub();
}
#[instrument]
fn sync_tracing_sub() {
warn!("event 2");
}
fn main() {
setup_tracing();
sync_tracing();
}
ΠΠ°ΠΊΡΠΎΡ #[instrument]
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠΈ (spans) Π΄Π»Ρ ΡΡΠ½ΠΊΡΠΈΠΉ, Π° ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊ (subscriber) Π½Π°ΡΡΡΠΎΠ΅Π½ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠΈ Π² stdout.
use tracing_subscriber::fmt::format::FmtSpan;
#[tracing::instrument] // ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ ΡΠ»Π΅Π΄ΠΈΡ Π·Π° Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΡΠ°Π±ΠΎΡΡ
async fn hello() {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
#[tokio::main] // cargo add tokio -F time,macros,rt-multi-thread
async fn main() -> anyhow::Result<()> {
let subscriber = tracing_subscriber::fmt()
.json()
.compact()
.with_file(true)
.with_line_number(true)
.with_thread_ids(true)
.with_target(false)
.with_span_events(FmtSpan::ENTER | FmtSpan::CLOSE) // Π²Ρ
ΠΎΠ΄ ΠΈ Π²ΡΡ
ΠΎΠ΄
.finish(); // ΠΏΠΎΡΠΎΠΊΠ° ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ
tracing::subscriber::set_global_default(subscriber).unwrap();
hello().await;
Ok(())
}
Π ΠΈΡΠΎΠ³Π΅ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π»ΠΎΠ³ ΡΠ°Π±ΠΎΡΡ ΠΏΠΎΡΠΎΠΊΠ° Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ Π·Π°Π΄Π΅ΡΠΆΠΊΠΈ:
2024-12-24T14:30:17.378906Z INFO ThreadId(01) hello: src/main.rs:3: {"message":"enter"} {}
2024-12-24T14:30:18.383596Z INFO ThreadId(01) hello: src/main.rs:3: {"message":"enter"} {}
2024-12-24T14:30:18.383653Z INFO ThreadId(01) hello: src/main.rs:3: {"message":"enter"} {}
2024-12-24T14:30:18.383675Z INFO ThreadId(01) hello: src/main.rs:3: {"message":"close","time.busy":"179Β΅s","time.idle":"1.00s"} {}
ΠΠ½Π΅ΡΠ½ΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ:
ΠΠ»Ρ Π·Π°ΠΏΠΈΡΠΈ ΠΆΡΡΠ½Π°Π»Π° ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΌΠΎΠ΄ΡΠ»Ρ tracing-appender
:
cargo add tracing-appender
Π£ Π½Π΅Π³ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΠ½ΠΊΡΠΈΠΉ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ Π·Π°ΠΏΠΈΡΠΈ Π² ΠΎΠ±Π»Π°ΡΠ½ΡΠ΅ ΡΠ»ΡΠΆΠ±Ρ ΡΠΈΠΏΠ° Datadog, Π½ΠΎ ΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΆΡΡΠ½Π°Π»Π° Ρ Π΄ΠΎΠ·Π°ΠΏΠΈΡΡΡ (ΠΌΠΈΠ½ΡΡΠ½ΠΎΠΉ, ΡΠ°ΡΠΎΠ²ΠΎΠΉ, Π΄Π½Π΅Π²Π½ΠΎΠΉ), Π° ΡΠ°ΠΊΠΆΠ΅ Π·Π°ΠΏΠΈΡΡ ΠΊΠ°ΠΊ Π½Π΅Π±Π»ΠΎΠΊΠΈΡΡΡΡΠ΅Π΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ.
ΠΡΠΈΠΌΠ΅Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π΅Π±Π»ΠΎΠΊΠΈΡΡΡΡΠ΅ΠΉ Π·Π°ΠΏΠΈΡΠΈ ΠΆΡΡΠ½Π°Π»Π° Π² ΡΠ°ΠΉΠ» (Π»ΡΡΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΊΠ°ΠΊ JSON), ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ Π²ΡΠ²ΠΎΠ΄ Π½Π° ΡΠΊΡΠ°Π½ ΠΈ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ ΡΠ°ΡΠΎΠ²ΠΎΠ³ΠΎ ΠΆΡΡΠ½Π°Π»Π° Ρ Π΄ΠΎΠ·Π°ΠΏΠΈΡΡΡ (rolling):
use tracing::{instrument, warn};
// ΡΡΠ½Π΅ΠΌ std::io::Write ΠΏΡΠΈΠ·Π½Π°ΠΊ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ Π½Π΅Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ
use tracing_subscriber::fmt::writer::MakeWriterExt;
fn setup_tracing() {
// ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠ°ΠΉΠ»Π° Ρ Π΄ΠΎΠ·Π°ΠΏΠΈΡΡΡ
let logfile = tracing_appender::rolling::hourly("/some/directory", "app-log");
// ΡΡΠΎΠ²Π΅Π½Ρ Π·Π°ΠΏΠΈΡΠΈ ΠΏΡΠΈ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ = INFO
let stdout = std::io::stdout.with_max_level(tracing::Level::INFO);
let subscriber = tracing_subscriber::fmt()
.with_max_level(tracing::Level::TRACE)
.json()
.compact()
.with_file(true)
.with_line_number(true)
.with_thread_ids(true)
.with_target(false)
.with_writer(stdout.and(logfile)) // ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π·Π°ΠΏΠΈΡΡ ΡΡΡ
.finish(); // Π² ΡΠ°ΠΉΠ» ΠΈ Π² stdout ΠΊΠΎΠ½ΡΠΎΠ»Ρ
tracing::subscriber::set_global_default(subscriber).unwrap();
}
#[instrument]
fn sync_tracing() {
warn!("event 1");
sync_tracing_sub();
}
#[instrument]
fn sync_tracing_sub() {
warn!("event 2");
}
fn main() {
setup_tracing();
sync_tracing();
}
ΠΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Ρ Π²Π°ΡΠΈΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² args()+collect() Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ env. ΠΡΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ ΠΈΡ Π² ΡΡΡΠΎΠΊΠΎΠ²ΡΠΉ Π²Π΅ΠΊΡΠΎΡ.
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
for arg in args.iter() {
println!("{}", arg);
} }
ΠΠ΅ΡΠ²ΡΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π²ΡΠ΅Π³Π΄Π° ΠΈΠ΄ΡΡ ΠΈΠΌΡ ΡΠ°ΠΌΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ.
ΠΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² CLI ΡΠ΄ΠΎΠ±Π½ΠΎ Π΄Π΅Π»Π°ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Clap
(0..3).for_each(|x| {println!("map i = {}", x * 2);});
.map(<closure>)
ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ ΠΈΡΠ΅ΡΠ°ΡΠΎΡΠ° Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΡ, ΡΡΠΎΠ±Ρ ΠΈΡ
ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ Π² Π΄ΡΡΠ³ΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄Π°Π»Π΅Π΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΠ΅.
.filter(<closure>)
Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΏΡΠ΅Π΄ΠΈΠΊΠ°Ρ Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ true. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΎΡΠ΄Π°Π²Π°ΡΡ Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΡ Π½Π΅Π»ΡΠ·Ρ, ΠΈ Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅.
let a = (0..3).map(|x| x * 2);
for i in a {
println!("map i = {}", i);
}
let a = (0..3).filter(|&x| x % 2 == 0);
for i in a {
println!("filter i = {}", i);
}
let a = (0..=3).map(|x| x * 2).map(|y| y - 1);
// ΠΏΠ΅ΡΠ²Π°Ρ ΠΈΡΠ΅ΡΠ°ΡΠΈΡ map(): 2, 4, 6
// Π²ΡΠΎΡΠ°Ρ ΠΈΡΠ΅ΡΠ°ΡΠΈΡ map(): 1, 3, 5
for i in a {
println!("{i}");
}
ΠΠ°ΠΆΠ΄Π°Ρ ΠΈΡΠ΅ΡΠ°ΡΠΈΡ fold
ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ 2 Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°:
fold
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΏΡΠ΅Π²ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π° Π² 1 Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅. ΠΡΠΈΠΌΠ΅Ρ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΠΌΠΌΡ Π²ΡΠ΅Ρ
ΡΡΡΠ½ΡΡ
ΡΠΈΡΠ΅Π»:
pub fn main() {
let even_sum = (1..=10).fold(0, |acc, num| if num % 2 == 0 { acc + num } else { acc });
println!("{even_sum:?}");
}
fold
ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΡΡΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠ΄ Π²ΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ Π½Π° ΠΎΡΠ±ΠΎΡ Π²ΡΠ΅Ρ
ΡΡΡΠ½ΡΡ
ΡΠΈΡΠ»Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ filter
ΠΈ ΠΈΡ
ΡΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ sum
:
(0..=10).filter(|n| *n % 2 == 0).sum()
ΠΠ°ΡΠ°Π²Π½Π΅ Ρ sum
ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠΏΡΠ»ΡΡΠ½Ρ product
ΠΈ collect
.
Π‘ΡΡΡΡΠΈΠΊ Ρ fold
Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠΈΡΠ»ΠΎΠ²ΠΎΠΉ, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, String:
pub fn giant_grunts(initial: char) -> String {
["Bee", "Fee", "Gee", "Fi", "Hi", "Fo", "Mo", "Fum", "Tum"].iter().fold(
String::new(),
|acc, grunt| if grunt.starts_with(initial) { acc + grunt } else { acc },
)}
pub fn main() {
let song = giant_grunts('F');
println!("{song:?}"); // "FeeFiFoFum"
}
ΠΠ°ΠΌΡΠΊΠ°Π½ΠΈΠ΅ all
Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ True
, Π΅ΡΠ»ΠΈ Π²ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π² Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ ΡΡΠ»ΠΎΠ²ΠΈΡ.
let a: Vec<i32> = vec![1, 2, 3, 4];
print!("{}\n", a.into_iter().all(|x| x > 1)); // false
ΠΠ»Ρ ΠΏΡΡΡΠΎΠ³ΠΎ Π²Π΅ΠΊΡΠΎΡΠ° Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΠ΅ all
Π²Π΅ΡΠ½ΡΡ True
:
let a: Vec<i32> = vec![];
print!("{}\n", a.into_iter().all(|x| x > 1)); // true
use std::collections::HashMap;
pub fn main() {
let num_vec = vec![1, 2, 1, 3, 5, 2, 1, 4, 6];
let mut number_count: HashMap<i32, i32> = HashMap::new();
for key in num_vec {
*number_count.entry(key).or_default() += 1;
}
/* for (k, v) in number_count {
print!("{} -> {}; ", k, v);
} */
number_count.iter().for_each(|(k, v)| {
print!("{} -> {}; ", k, v);
}); //ΡΠΈΠΊΠ» ΡΠ΅ΡΠ΅Π· Π·Π°ΠΌΡΠΊΠ°Π½ΠΈΠ΅ ΠΈΡΠ΅ΡΠ°ΡΠΎΡΠ°
}
ΠΡΠΎ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΏΠΎ ΠΎΠ±Π»Π°ΡΡΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡΠ΅. ΠΡΠΈ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠΈ Π½ΡΠΆΠ½ΠΎ Π²ΡΠ΅Π³Π΄Π° ΡΡΠ°Π·Ρ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΈΡ ΡΠΈΠΏ.
const MAX_LIMIT: u8 = 15; // ΡΠΈΠΏ u8 ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ Π½Π°Π΄ΠΎ ΡΠΊΠ°Π·Π°ΡΡ
fn main() {
for i in 1..MAX_LIMIT {
println!("{}", i);
} }
Π‘Π΄Π΅Π»Π°ΡΡ Π½ΠΎΠ²ΡΠΉ ΠΏΡΠΎΠ΅ΠΊΡ, Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π² Π½Π΅Π³ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ cargoΒ addΒ current_platform
. ΠΠ°Π»Π΅Π΅ ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΈ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΊΠΎΠ΄ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΡΠ΅Π΄Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ΠΈ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ:
use current_platform::{COMPILED_ON, CURRENT_PLATFORM};
fn main() {
println!("Run from {}! Compiled on {}.", CURRENT_PLATFORM, COMPILED_ON);
}
rustc -vV
rustc --print target-list
Π€ΠΎΡΠΌΠ°Ρ ΡΠΏΠΈΡΠΊΠ° ΠΈΠΌΠ΅Π΅Ρ ΠΏΠΎΠ»Ρ <arch><sub>-<vendor>-<sys>-<env>
, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, x86_64-apple-darwin
=> macOS Π½Π° ΡΠΈΠΏΠ΅ Intel.ΠΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ cross: cargo install cross
ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡ Π΅Π³ΠΎ ΠΏΠΎ ΠΏΡΡΠΈ $HOME/.cargo/bin
ΠΠ°Π»Π΅Π΅, Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π²Π°ΡΠΈΠ°Π½Ρ Docker Π² ΡΠΈΡΡΠ΅ΠΌΠ΅:
ΠΠ°ΠΏΡΡΠΊ ΠΊΠΎΠ΄Π° Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ ΠΏΠΎΠ΄ ΠΠ‘ Windows: cross run --target x86_64-pc-windows-gnu
=> Π² ΠΏΠ°ΠΏΠΊΠ΅ target/x86_64-pc-windows-gnu/debug
ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ EXE-ΡΠ°ΠΉΠ» Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠΌ.
βΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ ΠΏΡΠΎΡ
ΠΎΠ΄ΠΈΡ ΡΠ΅ΡΠ΅Π· WINE.
Cross ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π΄ΡΡΠ³ΠΈΡ ΠΏΠ»Π°ΡΡΠΎΡΠΌ. ΠΠΎΠ±Π°Π²ΠΊΠ° ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ:
mod tests {
use current_platform::{COMPILED_ON, CURRENT_PLATFORM};
#[test]
fn test_compiled_on_equals_current_platform() {
assert_eq!(COMPILED_ON, CURRENT_PLATFORM);
} }
ΠΠ°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ: cargo test
ΠΠ°ΠΏΡΡΡΠΈΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Ρ ΠΊΡΠΎΡΡ-ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠ΅ΠΉ: cross test --target x86_64-pc-windows-gnu
ΠΠ° Linux/macOS ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΏΡΠΎΠΉΠ΄ΡΡ, Π° Π²ΠΎΡ ΠΏΡΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ΠΏΠΎΠ΄ Windows - Π½Π΅Ρ:
`test tests::test_compiled_on_equals_current_platform … FAILED
ΠΠΎΠΆΠ½ΠΎ Π²ΠΏΠΈΡΠ°ΡΡ ΠΊΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΠΏΡΡΡΠΈΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π½Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠΉ ΠΠ‘, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠΎΠ»ΡΠΊΠΎ Π½Π° Windows:
use current_platform::{COMPILED_ON, CURRENT_PLATFORM};
#[cfg(target_os="windows")]
fn windows_only() {
println!("This will only print on Windows!");
}
fn main() {
println!("Run from {}! Compiled on {}.", CURRENT_PLATFORM, COMPILED_ON);
#[cfg(target_os="windows")]
{
windows_only();
}
}
Π’ΠΈΠΏ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½ΠΈΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²Π°ΡΡ Π²ΡΠ±ΠΎΡ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² Π² ΠΏΡΠ΅Π΄Π΅Π»Π°Ρ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π°.
enum Money {
Rub,
Kop
}
ΠΠ½Π°Π»ΠΎΠ³ switch Π² Π΄ΡΡΠ³ΠΈΡ ΡΠ·ΡΠΊΠ°Ρ , ΠΎΠ΄Π½Π°ΠΊΠΎ, ΠΊΡΡΡΠ΅: Π΅Π³ΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π΅ ΡΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΊ bool, Π° ΡΠ°ΠΊΠΆΠ΅ ΡΠ΅Π°ΠΊΡΠΈΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π±Π»ΠΎΠΊΠΎΠΌ:
fn main() {
let m = Money::Kop;
println!("Π― Π½Π°ΡΡΠ» ΠΊΠΎΡΠ΅Π»ΡΠΊ, Π° ΡΠ°ΠΌ {}p",match_value_in_kop(m));
}
fn match_value_in_kop(money: Money) -> u8 {
match money {
Money::Rub => 100,
Money::Kop => {
println!("Π‘ΡΠ°ΡΡΠ»ΠΈΠ²Π°Ρ ΠΊΠΎΠΏΠ΅ΠΉΠΊΠ°!");
1
} } }
ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΡΡΠ»ΠΎΠ²ΠΈΡ ΠΈ Π·Π°ΠΏΡΡΠΊ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π°:
struct State {
color: (u8, u8, u8),
position: Point,
quit: bool,
}
impl State {
fn change_color(&mut self, color: (u8, u8, u8)) {
self.color = color; }
fn quit(&mut self) {
self.quit = true; }
fn echo(&self, s: String) {
println!("{}", s); }
fn move_position(&mut self, p: Point) {
self.position = p; }
fn process(&mut self, message: Message) {
match message { // ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΈ Π·Π°ΠΏΡΡΠΊ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²
Message::Quit => self.quit(),
Message::Echo(x) => self.echo(x),
Message::ChangeColor(x, y, z) => self.change_color((x, y, z)),
Message::Move(x) => self.move_position(x),
} } }
Π ΡΠ»ΡΡΠ°Π΅, ΠΊΠΎΠ³Π΄Π° Π²ΡΠ±ΠΎΡ ΡΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΊ ΡΠΎΠΌΡ, ΡΡΠΎ ΠΌΡ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΠΌ 1 Π²Π°ΡΠΈΠ°Π½Ρ Ρ Π·Π°Π΄Π°Π½Π½ΡΠΌ ΠΏΠ°ΡΡΠ΅ΡΠ½ΠΎΠΌ ΠΈ Π΄Π°Π»Π΅Π΅ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΊΠΎΠ΄ ΠΏΡΠΈ ΡΡΠΏΠ΅Ρ Π΅, Π° Π² ΡΠ»ΡΡΠ°Π΅ Π½Π΅ΡΠ°Π²Π΅Π½ΡΡΠ²Π° Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅ΠΌ, ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΌΠ΅ΡΡΠΎ match ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡΠΎΡΠΊΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΡ if-let:
let config_max = Some(3u8);
match config_max {
Some(max) => println!("The maximum is configured to be {}", max),
_ => (), // Π΄ΡΡΠ³ΠΈΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΡ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ
}
ΠΡΠ΅Π²ΡΠ°ΡΠ°Π΅ΡΡΡ Π²:
let config_max = Some(3u8);
if let Some(max) = config_max {
println!("The maximum is configured to be {}", max);
}
ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ if-let - ΡΡΠΎ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°Ρ Π°Ρ, ΡΠΊΠΎΡΠ°ΡΠΈΠ²Π°Π΅Ρ ΠΊΠΎΠ΄, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π»ΠΈΡΠ°Π΅Ρ Π½Π°Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π°Π»ΠΈΡΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π½Π° Π²ΡΠ΅ Π²Π°ΡΠΈΠ°Π½ΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΊΠ°ΠΊ Π² ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠΈ match.
ΠΠ»Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π² ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ std::cmp, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΈΠΏΠ° enum Ordering Ρ Π²Π°ΡΠΈΠ°Π½ΡΠ°ΠΌΠΈ:
use std::cmp::Ordering;
use std:io;
fn main() {
let secret_number = 42;
let mut guess = String::new();
io::stdin()
.read_line(&guess)
.expect("Read line failed!");
let guess :i32 = guess.trim().parse()
.expect("Error! Non-number value entered.");
match guess.cmp(&secret_number) {
Ordering::Greater => println!("Number too big"),
Ordering::Less => println!("Number too small"),
Ordering::Equal => println("Found exact number!")
}
}
ΠΠ½Π΅ΡΠ½ΠΈΠ΅ ΡΡΡΠ»ΠΊΠΈ:
Π ΡΠ΄ ΠΎΡΠΈΠ±ΠΎΠΊ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ Π²ΡΠ»Π΅ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡΡΠ½ΡΡ Π²ΡΠ·Π²Π°ΡΡ Π²ΡΠ»Π΅Ρ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ panic!
:
fn main() {
panic!("Battery critically low! Shutting down to prevent data loss.");
}
ΠΡΠΈ ΡΡΠΎΠΌ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠ΅ΠΌΡ ΡΡΠ°ΡΠΈΡΡΡ Π½Π° Π·Π°ΠΊΡΡΡΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΎΡΠΈΡΡΠΊΡ ΡΡΠ΅ΠΊΠ° ΠΈ Π΄Π°Π½Π½ΡΡ . ΠΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π»ΠΎΠΆΠΈΡΡ ΡΡΠΎ Π½Π° ΠΠ‘, Π²Π²Π΅Π΄Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΡ Π² Cargo.toml:
[profile.release]
panic = 'abort'
ΠΠΎΠΏΡΡΡΠΈΠΌ, ΠΌΡ Π±Π΅ΡΡΠΌ Π²Π΅ΠΊΡΠΎΡ ΠΈΠ· ΡΡΡΠΎΠΊ-ΡΠΈΡΠ΅Π», ΡΠΊΠ»Π°Π΄ΡΠ²Π°Π΅ΠΌ ΠΈΡ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ ΡΡΠΌΠΌΡ ΠΊΠ°ΠΊ ΡΡΡΠΎΠΊΡ:
fn sum_str_vec (strs: Vec<String>) -> String {
let mut accum = 0i32;
for s in strs {
accum += to_int(&s); // to_int = Π·Π°Π³ΠΎΡΠΎΠ²ΠΊΠ°, ΡΠΌ. Π½ΠΈΠΆΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
}
return accum.to_string();
}
fn main() {
let v = vec![String::from("3"), String::from("4")]; // ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ Π²Π²ΠΎΠ΄
let total = sum_str_vec(v);
println!("Total equals: {:?}", total);
let v = vec![String::from("3"), String::from("abc")]; // ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΉ Π²Π²ΠΎΠ΄
let total = sum_str_vec(v);
println!("Total equals: {:?}", total);
}
ΠΠ»Ρ ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΠΈ ΡΡΡΠΎΠΊΠΈ Π² ΡΠΈΡΠ»Π°, Π½ΡΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ to_int
Π² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠΈ ΡΠΎ ΡΡΡΠ°ΡΠ΅Π³ΠΈΡΠΌΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΡΠ½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°. ΠΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ ΠΌΡ Π΄Π΅Π»Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ parse()
, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠΈΠΏ Result<T,E>
, Π³Π΄Π΅ T - Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, E - ΠΊΠΎΠ΄ ΠΎΡΠΈΠ±ΠΊΠΈ.
Π ΡΠ»ΡΡΠ°Π΅ Π½Π΅Π²Π΅ΡΠ½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ Π² ΠΏΠ°Π½ΠΈΠΊΠ΅. ΠΠ΅ΡΠΎΠ΄ unwrap()
Ρ ΡΠΈΠΏΠ° Result<T,E>
ΡΠ±ΠΈΡΠ°Π΅Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π° ΠΎΡΠΈΠ±ΠΊΠΈ ΠΈ Π΅ΡΡΡ Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠΎΠΌ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ ΠΎΡΠΈΠ±ΠΊΠΈ Π² ΡΡΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ Π±ΡΡΡ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ. ΠΡΠ»ΠΈ ΠΎΠ½Π° Π΅ΡΡΡ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΠ°Π΄Π°Π΅Ρ Ρ ΠΏΠ°Π½ΠΈΠΊΠΎΠΉ:
fn to_int(s: &str) -> i32 {
s.parse().unwrap() }
Π ΡΠ»ΡΡΠ°Π΅ Π½Π΅Π²Π΅ΡΠ½ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠΎΠΎΠ±ΡΠ°Π΅Ρ ΡΡΠ°Π·Ρ, Π·Π°Π΄Π°Π½Π½ΡΡ Π°Π²ΡΠΎΡΠΎΠΌ, Π΄Π°Π»Π΅Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ Π² ΠΏΠ°Π½ΠΈΠΊΠ΅. ΠΠ΅ΡΠΎΠ΄ expect()
Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ΅Π½ unwrap()
, Π½ΠΎ Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅:
fn to_int(s: &str) -> i32 {
s.parse().expect("Error converting from string") }
ΠΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ ΠΈ ΠΏΡΠΈΠ±Π°Π²ΠΈΡΡ ΠΊ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΡΠ΅ ΡΡΡΠΎΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΡΡΠΎ ΡΠ΄Π΅Π»Π°ΡΡ, ΠΏΡΠΎΠΈΠ³Π½ΠΎΡΠΈΡΠΎΠ²Π°ΡΡ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅. ΠΠ΅ΡΠΎΠ΄ unwrap_or()
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΊΠ°Π·Π°ΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ:
fn to_int(s: &str) -> i32 {
s.parse().unwrap_or(0) } // ΠΏΡΠΈ Π²Π²ΠΎΠ΄Π΅ "abc" Π²Π΅ΡΠ½ΡΡΡΡ 0, ΡΡΠΌΠΌΠ° = "3"
ΠΠΎΠ»Π΅Π΅ ΠΏΡΠ΅Π΄ΠΏΠΎΡΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π·Π°ΠΊΡΡΡΠΈΠ΅ unwrap_or_else()
, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΌΠ΅ΡΠΎΠ΄ unwrap_or()
Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ ΠΠ ΡΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π±ΡΠ΄Π΅Ρ ΠΎΡΡΠ°Π±ΠΎΡΠ°Π½Π° ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π°, ΠΠΠ ΠΠΠΠΠ‘ΠΠΠΠ‘Π’Π ΠΎΡ ΡΠΎΠ³ΠΎ, Π±ΡΠ΄Π΅Ρ Π»ΠΈ Π΅Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Some ΠΈΠ»ΠΈ None. ΠΡΠΎ ΠΏΠΎΡΠ΅ΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ Π³Π»ΡΠΊΠΈ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Π²Π½ΡΡΡΠΈ unwrap_or() ΡΠ»ΠΎΠΆΠ½ΡΡ
Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. ΠΠ°ΠΊΡΡΡΠΈΠ΅ unwrap_or_else()
Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠ»ΡΡΠ°Π΅ None, ΠΈΠ½Π°ΡΠ΅ ΠΆΠ΅ ΡΡΠ° Π²Π΅ΡΠΊΠ° Π½Π΅ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΡΡΡ:
fn to_int(s: &str) -> i32 {
s.parse().unwrap_or_else(|_| 0) }
ΠΠΌΠ΅ΡΡΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΡΠΈΡΠ»Π°, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ ΡΠΈΠΏ Option<ΡΠΈΡΠ»ΠΎ>
- Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΡΠΏΠ΅ΡΠ½ΠΎΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ, Π² Π½ΡΠΌ Π±ΡΠ΄Π΅Ρ Π»ΠΈΠ±ΠΎ ΡΠ°ΠΌΠΎ ΡΠΈΡΠ»ΠΎ, Π»ΠΈΠ±ΠΎ None
:
fn to_int(s: &str) -> Option<i32> {
s.parse().ok() // ok() ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅Ρ Result<T,E> Π² Option<T>
Π ΡΠΎΠ³Π΄Π° Π²ΡΠ·ΡΠ²Π°ΡΡΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ:
fn sum_str_vec (strs: Vec<String>) -> String {
let mut accum = 0i32;
for s in strs {
accum += match to_int(&s) {
Some(v) => v,
None => {
println!("Error converting a value, skipped");
0 // Π²Π΅ΡΠ½ΡΡΡΡ 0 +Π² Π»ΠΎΠ³ ΠΏΠΎΠΉΠ΄ΡΡ Π·Π°ΠΏΠΈΡΡ ΠΎ ΠΏΡΠΎΠΏΡΡΠΊΠ΅
}, } }
return accum.to_string();
}
ΠΠΎΠ»Π΅Π΅ ΠΊΠΎΡΠΎΡΠΊΠΈΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π·Π°ΠΏΠΈΡΠΈ ΡΠ΅ΡΠ΅Π· if let
:
fn sum_str_vec (strs: Vec<String>) -> String {
let mut accum = 0i32;
for s in strs {
if let Some(val) = to_int(&s) {
accum += val;
} else { println!("Error converting a value, skipped"); }
}
return accum.to_string();
}
Π’ΠΈΠΏ Option<T>
ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ ΠΌΠ΅ΡΠΎΠ΄ unwrap_or()
, ΠΎΡΡΡΠ΄Π° Π΅ΡΡ Π²Π°ΡΠΈΠ°Π½Ρ Π·Π°ΠΏΠΈΡΠΈ:
fn sum_str_vec (strs: Vec<String>) -> String {
let mut accum = 0i32;
for s in strs {
accum += to_int(&s).unwrap_or(0); // ΡΠ°ΡΠΊΡΡΠ²Π°Π΅ΠΌ Option<T>
}
return accum.to_string();
}
ΠΠΌΠ΅ΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ, Π² ΡΠ»ΡΡΠ°Π΅ ΠΊΠ°ΠΊΠΈΡ
-Π»ΠΈΠ±ΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, ΠΌΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ None
:
fn sum_str_vec (strs: Vec<String>) -> Option<String> {
let mut accum = 0i32;
for s in strs {
accum += to_int(&s)?; // Π² ΡΠ»ΡΡΠ°Π΅ None, ? ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π΅Π³ΠΎ Π΄Π°Π»Π΅Π΅ Π½Π° Π²ΡΡ
ΠΎΠ΄
}
Some(accum.to_string()) // Π½Π° Π²ΡΡ
ΠΎΠ΄ ΠΏΠΎΠΉΠ΄ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ None
}
ΠΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π² ΠΎΡΠ½ΠΎΠ²Π½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Ρ ΠΎΠ±ΡΡΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π·Π°Π²ΠΎΠ΄ΠΈΠΌ ΡΡΡΡΠΊΡΡΡΡ ΠΏΠΎΠ΄ ΠΎΡΠΈΠ±ΠΊΡ, ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ ΡΠΆΠ΅ Π½Π΅ ΠΎΠ±ΡΠ΅ΠΊΡ Option<T>
, Π° ΠΎΠ±ΡΠ΅ΠΊΡ Result<T,E>
, Π³Π΄Π΅ E = SummationError. ΠΠ»Ρ ΡΠ°ΠΊΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ ok_or()
, ΠΊΠΎΡΠΎΡΡΠΉ Π»ΠΈΠ±ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π»ΠΈΠ±ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°:
#[derive(Debug)]
struct SummationError;
fn sum_str_vec (strs: Vec<String>) -> Result<String, SummationError> {
let mut accum = 0i32;
for s in strs {
accum += to_int(&s).ok_or(SummationError)?;
}
Ok(accum.to_string())
}
ΠΠΌΠ΅ΡΡΠΎ Π²ΡΠ΄ΡΠΌΡΠ²Π°ΡΡ ΡΠ²ΠΎΠΉ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΠΈΠΏ ΠΈ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ²ΠΎΠ΄ ΠΌΠ΅ΡΠΎΠ΄Π° parse()
ΠΈΠ· Result<T,E>
Π² Option<T>
, Π° ΠΏΠΎΡΠΎΠΌ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠ°Π·Ρ ΠΏΡΠΎΡΠ°ΡΠΈΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡΠ΅ Result<T,E>
Π² Π³Π»Π°Π²Π½ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ:
use std::num::ParseIntError; // ΡΠΈΠΏ ΠΎΡΠΈΠ±ΠΊΠΈ Π±Π΅ΡΡΠΌ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ
fn to_int(s: &str) -> Result<i32, ParseIntError> {
s.parse() // parse Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΏΡΠΎΡΡΠΎ Result<T,E>
}
fn sum_str_vec (strs: Vec<String>) -> Result<String, ParseIntError> {
let mut accum = 0i32;
for s in strs {
accum += to_int(&s)?; } // ? ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° Π΄Π°Π»Π΅Π΅
Ok(accum.to_string())
}
ΠΠ΄Π½Π°ΠΊΠΎ, ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΡΠΊΡΡΡΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ ΡΠ°Π±ΠΎΡΡ ΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΡ Π³Π»Π°Π²Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π΅ΠΉ ΠΎΡΠΈΠ±ΠΊΡ Π² ΠΏΠΎΠ½ΡΡΠ½ΠΎΠΌ Π²ΠΈΠ΄Π΅, Π±Π΅Π· ΡΠ°Π·ΡΡΡΠ½Π΅Π½ΠΈΡ Π΄Π΅ΡΠ°Π»Π΅ΠΉ Π΅Ρ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠ°Π½ΡΠ»ΡΡΠΈΡ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΡΠ½ΠΎΠΉ Π² ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΠΈΠΏ, ΠΈ Π΄Π°Π»Π΅Π΅ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ map_err():
use std::num::ParseIntError;
#[derive(Debug)]
struct SummationError;
fn to_int(s: &str) -> Result<i32, ParseIntError> {
s.parse()
}
fn sum_str_vec (strs: Vec<String>) -> Result<String, SummationError> {
let mut accum = 0i32;
for s in strs {
accum += to_int(&s).map_err(|_| SummationError)?; // ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ ΠΎΡΠΈΠ±ΠΊΠΈ
} // ΠΏΠ΅ΡΠ΅Π΄ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅ΠΉ
Ok(accum.to_string())
}
?
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ ?
ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΡΠ½ΠΊΡΠΈΡΡ
Π΄Π»Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΡ
Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΡΠΈΠΏΠ° Result<T,E>
, Option<T>
ΠΈΠ»ΠΈ ΠΈΠ½ΡΡ
Π΄Π°Π½Π½ΡΡ
ΡΠΎ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΠΌ FromResidual
. ΠΠ»Ρ ΡΠ°Π±ΠΎΡΡ ΡΠ°ΠΊΠΎΠ³ΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΏΡΠΎΠΏΠΈΡΠ°Π½ Π²ΠΎΠ·Π²ΡΠ°Ρ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° Π΄Π°Π½Π½ΡΡ
.
ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ?
Π½Π° Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΡΠΈΠΏΠ° Result<T,E>
ΠΈΠ»ΠΈ Option<T>
, ΠΎΡΠΈΠ±ΠΊΠ° Err(e)
ΠΈΠ»ΠΈ None
Π±ΡΠ΄Π΅Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½Π° ΡΠ°Π½ΠΎ ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ, Π° Π² ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅Ρ
Π° - Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π²Π΅ΡΠ½ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ, ΠΈ ΡΡΠ½ΠΊΡΠΈΡ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ ΡΠ°Π±ΠΎΡΡ.
ΠΡΠΈΠΌΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΡΠΈΠΌΠ²ΠΎΠ» 1ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΡΠ΅ΠΊΡΡΠ°:
fn last_char_of_first_line(text: &str) -> Option<char> {
text.lines().next()?.chars().last()
} // lines() Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΈΡΠ΅ΡΠ°ΡΠΎΡ Π½Π° ΡΠ΅ΠΊΡΡ
// next() Π±Π΅ΡΡΡ ΠΏΠ΅ΡΠ²ΡΡ ΡΡΡΠΎΠΊΡ ΡΠ΅ΠΊΡΡΠ°. ΠΡΠ»ΠΈ ΡΠ΅ΠΊΡΡ ΠΏΡΡΡΠΎΠΉ - ΡΡΠ°Π·Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ None
Π€ΡΠ½ΠΊΡΠΈΡ read_dir:
use std::fs;
fn main() {
let paths = fs::read_dir("./").unwrap();
for path in paths {
println!("{}", path.unwrap().path().display())
}
}
use std::fs;
use std::process;
fn main() {
let paths = fs::read_dir("./").unwrap();
for path in paths {
let pathbuf = path.unwrap().path();
println!("{:?}", fs::canonicalize(&pathbuf));
}
println!("\nPID = {}\n", process::id());
}
ΠΠ»Ρ ΡΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ², Π½ΡΠΆΠ½ΠΎ ΡΠ½Π°ΡΠ°Π»Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ: FIle - ΠΎΡΠΊΡΡΡΠΈΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ Read - ΡΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΡΠΉ Π²Ρ ΠΎΠ΄ΠΈΡ Π² prelude.
se std::fs::File; // ΠΈΠΌΠΏΠΎΡΡ File
use std::io::prelude::*; // ΠΈΠΌΠΏΠΎΡΡ Read
fn main() {
// ΡΠΈΡΠ°Π΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ Π² ΠΊΠΎΡΠ½Π΅ ΠΏΡΠΎΠ΅ΠΊΡΠ°.
let mut file = File::open("access.log.10").expect("File not opened!");
let mut contents = String::new(); // Π·Π°ΠΊΠ°ΡΠ°ΡΡ ΡΠ°ΠΉΠ» Π² ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ-ΡΡΡΠΎΠΊΡ
file.read_to_string(&mut contents).expect("Cannot read file!");
println!("File contents: \n\n{}",contents);
}
Π§ΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° Π² ΠΏΠ°ΠΌΡΡΡ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ ΠΊΠ°ΠΊ Π²Π΅ΠΊΡΠΎΡΠ° Π±Π°ΠΉΡΠΎΠ² - Π΄Π»Ρ Π±ΠΈΠ½Π°ΡΠ½ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ², Π»ΠΈΠ±ΠΎ Π΄Π»Ρ ΡΠ°ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΊ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠΌΡ:
use std::io::Read;
use std::{env, fs, io, str};
fn main() -> io::Result<()> {
let mut file = fs::File::open("test_file.txt")?;
let mut contents = Vec::new();
file.read_to_end(&mut contents);
println!("File contents: {:?}", contents); // Π²ΡΠ²ΠΎΠ΄ Π±Π°ΠΉΡ
let text = match str::from_utf8(&contents) { // ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ Π² ΡΡΡΠΎΠΊΡ UTF8
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8: {e}"),
};
println!("Result: {text}"); // Π²ΡΠ²ΠΎΠ΄ ΡΡΡΠΎΠΊΠΎΠΉ
Ok(())
}
ΠΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅ File ΡΠ°ΠΊΠΆΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΈ Π±ΡΡΠ΅ΡΠ° ΡΡΠ΅Π½ΠΈΡ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΡΠΊΡΡΡΠΈΡ ΡΠ°ΠΉΠ»Π° ΠΈ ΡΡΠ΅Π½ΠΈΡ.
use std::io::{BufRead, BufReader};
use std::{env, fs, io};
fn main() -> io::Result<()> {
let file = fs::File::open("textfile.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() { // io::BufRead::lines()
let line = line?;
println!("{line}");
}
Ok(())
use std::fs::File;
use std::io::prelude::*;
fn main() {
let mut file = File::create("report.log").expect("File not created!");
file.write_all(b"report.log");
}
Π Rust Π΅ΡΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠΈ IF, ELSE IF, ELSE:
let test_number = 6;
if test_number % 4 == 0 {
println!("Divisible by 4");
} else if test_number % 3 == 0 { // ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ Π½Π° ΠΏΠ΅ΡΠ²ΠΎΠΌ
println!("Divisible by 3"); // Π²ΡΠΏΠΎΠ»Π½ΠΈΠΌΠΎΠΌ ΡΡΠ»ΠΎΠ²ΠΈΠΈ, Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠΈΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ
} else if test_number % 2 == 0 { // ΠΏΡΠΎΠΏΡΡΠΊΠ°ΡΡΡΡ.
println!("Divisible by 2");
} else {
println!("Number is not divisible by 4, 3 or 2");
}
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΈΡ IF ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ (expression), ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΠ΅:
let condition = true;
let number = if condition { "aa" } else { "ab" }; // ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° IF
println!("Number is {number}");
Π’ΡΠΈ Π²Π°ΡΠΈΠ°Π½ΡΠ° ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠΊΠ»: ΡΠ΅ΡΠ΅Π· ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΡ loop, while, for.
LOOP - ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ Π²Π΅ΡΠ½ΡΡ ΡΠΈΠΊΠ»ΠΎΠ². ΠΠΎΠ½ΡΡΡΡΠΊΡΠΈΡ LOOP ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ (expression), ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΠ΅.
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // Π²ΡΡ
ΠΎΠ΄ ΠΈΠ· Π²Π΅ΡΠ½ΠΎΠ³ΠΎ ΡΠΈΠΊΠ»Π°
}
}; // ";" Π½ΡΠΆΠ½ΠΎ, Ρ.ΠΊ. Π±ΡΠ»ΠΎ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅
println!("The result is {result}");
ΠΡΠ»ΠΈ Π΄Π΅Π»Π°ΡΡ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠ΅ ΡΠΈΠΊΠ»Ρ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡ ΠΈΡ ΠΌΠ΅ΡΠΊΠΎΠΉ, ΡΡΠΎΠ±Ρ Π²ΡΡ ΠΎΠ΄ΠΈΡΡ Ρ break Π½Π° Π½ΡΠΆΠ½ΡΠΉ ΡΡΠΎΠ²Π΅Π½Ρ.
let mut count = 0;
'counting_up: loop { // ΠΌΠ΅ΡΠΊΠ° Π²Π½Π΅ΡΠ½Π΅Π³ΠΎ ΡΠΈΠΊΠ»Π°
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {
break;
}
if count == 2 {
break 'counting_up; // goto ΠΌΠ΅ΡΠΊΠ°
}
remaining -= 1;
}
count += 1;
}
println!("End count = {count}");
WHILE - ΡΠΈΠΊΠ» Ρ ΡΡΠ»ΠΎΠ²ΠΈΠ΅ΠΌ. ΠΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠ΅ΡΠ΅Π· loop, Π½ΠΎ Ρ while ΡΠΈΠ»ΡΠ½ΠΎ ΠΊΠΎΡΠΎΡΠ΅.
let mut number = 10;
while number != 0 {
println!("{number}!");
number -= 1;
}
println!("ΠΠΠΠ£Π‘Π!");
FOR - ΡΠΈΠΊΠ» ΠΏΠΎ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π°ΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ². Π ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ ΠΏΠΎΠ΄ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠΈΡΠ΅Π».
for i in (1..10).rev() { // .rev() - Π²ΡΠ΄Π°ΡΠ° ΠΏΠΎΠ΄ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π° Π² ΠΎΠ±ΡΠ°ΡΠ½ΡΡ ΡΡΠΎΡΠΎΠ½Ρ
println!("Value: {i}");
}
println!("ΠΠΠΠ£Π‘Π!");
Generics Π½ΡΠΆΠ½Ρ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ Π½Π΅ ΠΏΠΎΠ²ΡΠΎΡΡΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ-ΠΆΠ΅ ΠΊΠΎΠ΄ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π· Π΄Π»Ρ ΡΠ°Π·Π½ΡΡ ΡΠΈΠΏΠΎΠ² Π΄Π°Π½Π½ΡΡ . ΠΡΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΡΡΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ ΡΠΏΠΎΡΠΎΠ±ΠΎΠ² ΡΠΊΠΎΠ½ΠΎΠΌΠΈΠΈ Π½Π° ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΠΈ ΠΊΠΎΠ΄Π° Π½Π°ΡΠ°Π²Π½Π΅ Ρ ΠΌΠ°ΠΊΡΠΎΡΠ°ΠΌΠΈ ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°ΠΌΠΈ traits. ΠΡΠΈΠΌΠ΅Ρ: Π½ΡΠΆΠ½ΠΎ ΡΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ 2 Π½Π°Π±ΠΎΡΠ° Π΄Π°Π½Π½ΡΡ - ΠΌΠ°ΡΡΠΈΠ² ΡΠΈΡΠ΅Π», ΠΌΠ°ΡΡΠΈΠ² ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ².
fn largest_i32(n_list: &[i32]) -> &i32 {
let mut largest_num = &n_list[0];
for i in n_list {
if largest_num < i {
largest_num = i;
}
}
largest_num
}
fn largest_char(n_list: &[char]) -> &char {
let mut largest_char = &n_list[0];
for i in n_list {
if largest_char < i {
largest_char = i;
}
}
largest_char
ΠΠΌΠ΅ΡΡΠΎ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΏΠΈΡΠ°ΡΡ 2 ΠΏΠΎΡΡΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΏΠΎΠ΄ 2 ΡΠΈΠΏΠ° Π΄Π°Π½Π½ΡΡ , ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΠΈΡΡ ΠΎΠ±Π° ΡΠΈΠΏΠ° Π² 1 ΡΡΠ½ΠΊΡΠΈΡ, ΡΠΊΠ°Π·Π°Π² “Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΡΠΈΠΏ”.
ΠΡΠΆΠ½ΠΎ ΡΡΠ΅ΡΡΡ, ΡΡΠΎ Π½Π΅ Π²ΡΠ΅ ΡΠΈΠΏΡ Π΄Π°Π½Π½ΡΡ ΠΈΠΌΠ΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΠ±ΠΎΠΉ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π²ΡΡΡΡΠΎΠΈΡΡ ΠΈΡ Π² ΠΏΠΎΡΡΠ΄ΠΎΠΊ (Order). ΠΠΎΡΡΠΎΠΌΡ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½ΠΈΠΆΠ΅ Π½Π°Π΄ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΡ ΡΠΈΠΏ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠΌ-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΠΌ (trait) ΠΏΠΎΡΡΠ΄ΠΊΠ°.
fn largest_universal<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
// <T> = Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΡΠΈΠΏ, ΡΠΎ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΠΌ ΡΠΏΠΎΡΡΠ΄ΠΎΡΠΈΠ²Π°Π½ΠΈΡ PartialOrd
let mut largest = &list[0];
for item in list {
if largest < item {
largest = item;
}
}
largest
}
fn main() {
let num_list = vec![11, 6, 33, 56, 13];//ΡΠΏΠΎΡΡΠ΄ΠΎΡΠΈΡΡ ΡΠΈΡΠ»Π°
println!("Largest number: {}", largest_universal(&num_list));
let char_list = vec!['y','m','a','q'];//ΡΠΏΠΎΡΡΠ΄ΠΎΡΠΈΡΡ ΡΠΈΠΌΠ²ΠΎΠ»Ρ Π² ΡΠΎΠΉ ΠΆΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ
println!("Largest char: {}", largest_universal(&char_list));
}
ΠΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΡΡΡΠΊΡΡΡΡ, ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ ΠΊΠΎΡΠΎΡΡΡ Π·Π°ΡΠ°Π½Π΅Π΅ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½. ΠΡΠΈΡΡΠΌ Π² ΠΎΠ΄Π½ΠΎΠΉ ΡΡΡΡΠΊΡΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π·Π½ΡΡ ΡΠΈΠΏΠΎΠ².
struct Point<T,U> { // <T> ΠΈ <U> - 2 ΡΠ°Π·Π½ΡΡ
ΡΠΈΠΏΠ°
x: T,
y: U,
}
let integer = Point{x:5,y:6}; // Π² ΠΎΠ±Π° ΠΏΠΎΠ»Ρ ΠΏΠΈΡΠ΅ΠΌ ΡΠΈΡΠ»Π° ΡΠΈΠΏΠ° i32
let float_int = Point{x:1,y:4.2}; // Π² ΠΏΠΎΠ»Ρ ΠΏΠΈΡΠ΅ΠΌ ΡΠ°Π·Π½ΡΠ΅ ΡΠΈΠΏΡ i32 ΠΈ f32
ΠΠ½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΎ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠ΅ ΡΠΈΠΏΡ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ Π² ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½ΠΈΡΡ :
enum Option<T> {
Some(T), // <T> - Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π»ΡΠ±ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΠ»ΠΈ Π½Π΅Ρ
None,
}
enum Result<T, E> {
Ok(T), // T - ΡΠΈΠΏ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΡΡΠΏΠ΅ΡΠ½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ
Err(E), // Π - ΡΠΈΠΏ ΠΎΡΠΈΠ±ΠΊΠΈ
}
ΠΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΠΏΠΈΡΠ°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ Π½Π°Π΄ Π΄Π°Π½Π½ΡΠΌΠΈ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°. ΠΠ°ΠΆΠ½ΠΎ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ ΠΌΠ΅ΡΠΎΠ΄Π° ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΏΡΠΈ ΡΡΠΎΠΌ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΡΠΈΠΏ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠΌΠΎΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΡ ΠΎΡΠ΄Π΅Π»ΠΈΡΡ Π΅Π³ΠΎ ΠΎΡ ΠΎΠ±ΡΡΠ½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° Π΄Π°Π½Π½ΡΡ . ΠΠΎΠΆΠ½ΠΎ ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π΄Π»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΡ ΡΠΈΠΏΠΎΠ² Π΄Π°Π½Π½ΡΡ , Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΡΡΡΡ ΡΠ°ΡΡΡΠΎΡΠ½ΠΈΡ Π΄ΠΎ ΡΠΎΡΠΊΠΈ ΠΎΡ ΡΠ΅Π½ΡΡΠ° ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°Ρ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΠΈΡΠ΅Π» Ρ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΡΠΎΡΠΊΠΎΠΉ. ΠΠ»Ρ Π΄ΡΡΠ³ΠΈΡ ΡΠΈΠΏΠΎΠ² Π΄Π°Π½Π½ΡΡ ΠΌΠ΅ΡΠΎΠ΄ ΡΠ°ΡΡΡΡΠ° ΡΠ°Π±ΠΎΡΠ°ΡΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ:
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> { // ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΡΠΈΠΏ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅
fn show_x(&self) -> &T { // ΠΌΠ΅ΡΠΎΠ΄ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΏΠΎΠ»Π΅ Π΄Π°Π½Π½ΡΡ
&self.x
} }
impl Point<f32> { // ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΡΠΈΠΏ float Π² ΠΌΠ΅ΡΠΎΠ΄Π΅,
// ΡΡΠΎΠ±Ρ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ Π½Π΅Π³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΡΡΡΡ. ΠΠ»Ρ Π½Π΅-float ΠΌΠ΅ΡΠΎΠ΄ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
} }
fn main() {
let p = Point{x:5,y:6};
println!("P.x = {}",p.show_x()); // Π²ΡΠ·ΠΎΠ² ΠΌΠ΅ΡΠΎΠ΄Π° Π΄Π»Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° p
}
ΠΠΎΠ΄ Ρ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ Π½Π΅ Π·Π°ΠΌΠ΅Π΄Π»ΡΠ΅Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡ ΠΈ ΠΏΠΎΠ΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠ΅ ΡΠΈΠΏΡ Π²Π΅Π·Π΄Π΅, Π³Π΄Π΅ Π²ΠΈΠ΄ΠΈΡ generics (“monomorphization” of code).
ΠΡΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠ°Ρ ΡΡΡΡΠΊΡΡΡΠ° ΡΠ»ΠΎΠ²Π°ΡΡ (“dictionary” Π² Python), ΠΊΠΎΡΠΎΡΠ°Ρ Ρ ΡΠ°Π½ΠΈΡ ΠΏΠ°ΡΡ “ΠΊΠ»ΡΡ->Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅”. Π Rust Prelude ΠΎΠ½Π° Π½Π΅ Π²Ρ ΠΎΠ΄ΠΈΡ, ΠΌΠ°ΠΊΡΠΎΡΠ° ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ. ΠΠΎΡΡΠΎΠΌΡ Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ ΡΠ²Π½ΠΎ ΠΈ ΡΠ²Π½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΡΡΡΠΊΡΡΡΡ.
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Alpha"),1);
scores.insert(String::from("Beta"),2);
scores.insert(String::from("Gamma"),3);
}
ΠΡΠ΅ ΠΊΠ»ΡΡΠΈ Hashmap Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½Ρ ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°, Π²ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°.
ΠΠ½Π°ΡΠ΅Π½ΠΈΡ Ρ ΠΊΡΡΠΈ ΡΠΈΠΏΠ° String ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ°ΡΡΡΡ (move) Π² Hashmap, ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ ΠΈΡ Π²Π»Π°Π΄Π΅Π»ΡΡΠ΅ΠΌ.
ΠΠ·ΡΡΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠΎ ΠΊΠ»ΡΡΡ ΠΈΠ· Hashmap Ρ ΠΏΠΎΠΌΠΎΡΡΡ get
Π½ΡΠΆΠ½ΠΎ ΡΠΎΠΏΡΠΎΠ²ΠΎΠΆΠ΄Π°ΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΎΠΉ - Π΅ΡΡΡ Π»ΠΈ Π² ΠΏΠ°ΠΌΡΡΠΈ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌΡΠ΅ ΠΊΠ»ΡΡ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅:
let name = String::from("Gamma");
if let Some(letter_num) = scores.get(&name) {
println!("{}",letter_num);
} else { println!("Value not in HashMap!"); }
ΠΡΠ΅ΡΠ°ΡΠΈΡ ΠΏΠΎ Hashmap ΠΏΠΎΡ ΠΎΠΆΠ° Π½Π° ΠΈΡΠ΅ΡΠ°ΡΠΈΡ ΠΏΠΎ Π²Π΅ΠΊΡΠΎΡΡ:
for (key, value) in &scores {
println!("{key} -> {value}"); }
ΠΡΡΡ ΡΡΠ΄ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΉ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π² Hashmap:
scores.insert(String::from("Gamma"),3); // Π²ΡΡΠ°Π²ΠΊΠ° Π΄Π²Π°ΠΆΠ΄Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ
scores.insert(String::from("Gamma"),6); // ΠΊΠ»ΡΡΡ ΡΠΎΡ
ΡΠ°Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅
scores.entry(String::from("Delta")).or_insert(4); // entry ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ Π½Π°Π»ΠΈΡΠΈΠ΅
// Π·Π½Π°ΡΠ΅Π½ΠΈΡ, or_insert Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ mut ΡΡΡΠ»ΠΊΡ Π½Π° Π½Π΅Π³ΠΎ, Π»ΠΈΠ±ΠΎ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅Ρ Π½ΠΎΠ²ΠΎΠ΅
// Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ mut ΡΡΡΠ»ΠΊΡ Π½Π° ΡΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅.
use std::collections::HashMap;
let mut map: HashMap<&str, u32> = HashMap::new();
map.entry("poneyland") // ΠΏΠ΅ΡΠ²ΠΎΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅
.and_modify(|e| { *e += 1 })
.or_insert(42); // Π΄ΠΎΠ±Π°Π²ΠΈΡ ΠΊΠ»ΡΡ "poneyland: 42"
assert_eq!(map["poneyland"], 42);
map.entry("poneyland") // Π²ΡΠΎΡΠΎΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π°ΠΉΠ΄ΡΡ ΠΊΠ»ΡΡ ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ
.and_modify(|e| { *e += 1 }) // ΠΈ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΡΠ΅Ρ Π΅Π³ΠΎ
.or_insert(42);
assert_eq!(map["poneyland"], 43);
use std::collections::HashMap;
let mut map: HashMap<&str, usize> = HashMap::new();
map
.entry("poneyland")
.or_insert_with_key(|key| key.chars().count());
assert_eq!(map["poneyland"], 9);
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}",map); // {"wonderful": 1, "hello": 1, "world": 2}
ΠΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΎ ΡΠΈΠΏΡ defaultdict
Π² Python. ΠΠ°ΠΏΠΎΠ»Π½ΡΡΡ ΠΊΠ»ΡΡΠ°ΠΌΠΈ HashMap:
use std::collections::HashMap;
pub fn main() {
let num_vec = vec![1, 2, 1, 3, 5, 2, 1, 4, 6];
let mut number_count: HashMap<i32, i32> = HashMap::new();
for key in num_vec {
*number_count.entry(key).or_default() += 1;
}
for (k, v) in number_count {
print!("{} -> {}; ", k, v);
}
}
// 4 -> 1; 1 -> 3; 2 -> 2; 6 -> 1; 5 -> 1; 3 -> 1;
External link: https://doc.rust-lang.org/stable/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
mod test
, ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΊΠ°ΡΡ Π΅Π³ΠΎ ΠΊΠΎΠ΄ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· ΠΌΠ΅ΡΡ:
mod automa
. ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΊΠ°ΡΡ ΠΊΠΎΠ΄ ΠΏΠΎΠ΄ΠΌΠΎΠ΄ΡΠ»Ρ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· ΠΌΠ΅ΡΡ:
crate::test::automa::robot
;pub mod
Π²ΠΌΠ΅ΡΡΠΎ mod
;use
Π½ΡΠΆΠ½ΠΎ Π΄Π»Ρ ΡΠΎΠΊΡΠ°ΡΠ΅Π½ΠΈΡ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ ΠΏΡΡΠΈ Π΄ΠΎ ΠΊΠΎΠ΄Π°: use crate::test::automa::robot
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π΄Π°Π»Π΅Π΅ ΠΏΠΈΡΠ°ΡΡ ΠΏΡΠΎΡΡΠΎ robot
Π΄Π»Ρ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΊ Π΄Π°Π½Π½ΡΠΌ ΡΡΠΎΠ³ΠΎ ΡΠΈΠΏΠ°.ΠΡΠΆΠ½ΠΎ Π»ΠΈΡΡ Π΅Π΄ΠΈΠ½ΠΎΠΆΠ΄Ρ Π²Π½Π΅ΡΡΠΈ Π²Π½Π΅ΡΠ½ΠΈΠΉ ΡΠ°ΠΉΠ» Ρ ΠΏΠΎΠΌΠΎΡΡΡ mod
Π² Π΄Π΅ΡΠ΅Π²Π΅ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ, ΡΡΠΎΠ±Ρ ΠΎΠ½ ΡΡΠ°Π» ΡΠ°ΡΡΡΡ ΠΏΡΠΎΠ΅ΠΊΡΠ°, ΠΈ ΡΡΠΎΠ±Ρ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΌΠΎΠ³Π»ΠΈ Π½Π° Π½Π΅Π³ΠΎ ΡΡΡΠ»Π°ΡΡΡΡ. Π ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ mod
Π½Π΅ Π½Π°Π΄ΠΎ ΡΡΡΠ»Π°ΡΡΡΡ, mod
- ΡΡΠΎ ΠΠ include
ΠΈΠ· Python ΠΈ Π΄ΡΡΠ³ΠΈΡ
ΡΠ·ΡΠΊΠΎΠ² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
my_crate
βββ Cargo.lock
βββ Cargo.toml
βββ src
βββ test
βΒ Β βββ automa.rs
βββ test.rs
βββ main.rs
ΠΠ»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ°, Π²ΠΎΠ·ΡΠΌΡΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ, ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡΡΡ ΡΠ°Π±ΠΎΡΡ ΡΠ΅ΡΡΠΎΡΠ°Π½Π°. Π Π΅ΡΡΠΎΡΠ°Π½ Π΄Π΅Π»ΠΈΡΡΡ Π½Π° ΡΠ°ΡΡΠΈ front - ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΡΠ΅ΡΠΈΡΠ΅Π»Π΅ΠΉ, ΠΈ back - ΠΊΡΡ Π½Ρ, ΠΌΠΎΠΉΠΊΠ°, Π±ΡΡ Π³Π°Π»ΡΠ΅ΡΠΈΡ.
mod front {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
ΠΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ΄ΡΠ»Ρ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ pub
Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ Π΅Π³ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌΠΈ. ΠΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎΡΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΏΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΡΡΠΈ:
mod front_of_house {
pub mod hosting { // ΠΌΠΎΠ΄ΡΠ»Ρ ΠΏΡΠ±Π»ΠΈΡΠ΅Π½, ΡΡΠΎΠ±Ρ ΠΊ Π½Π΅ΠΌΡ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ
pub fn add_to_waitlist() {} // ΡΡΠ½ΠΊΡΠΈΡ ΡΠ²Π½ΠΎ ΠΏΡΠ±Π»ΠΈΡΠ½Π°
// Π½Π΅ΡΠΌΠΎΡΡΡ Π½Π° ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎΡΡΡ ΠΌΠΎΠ΄ΡΠ»Ρ, ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ Π½Π΅Π»ΡΠ·Ρ
// Π΅ΡΠ»ΠΈ ΠΎΠ½Π° Π½Π΅ΠΏΡΠ±Π»ΠΈΡΠ½Π°
}
}
pub fn eat_at_restaurant() {
// ΠΠ±ΡΠΎΠ»ΡΡΠ½ΡΠΉ ΠΏΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΡΠ΅Π½Ρ - ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ crate
crate::front_of_house::hosting::add_to_waitlist();
// ΠΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΏΡΡΡ
front_of_house::hosting::add_to_waitlist();
}
ΠΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ΅ΡΠ΅Π· super
(Π°Π½Π°Π»ΠΎΠ³ “..” Π² ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅):
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order(); // Π²ΡΠ·ΠΎΠ² ΡΡΠ½ΠΊΡΠΈΠΈ Π² ΡΠΎΠ΄ΠΈΡΠ΅Π»ΡΡΠΊΠΎΠΌ ΠΌΠΎΠ΄ΡΠ»Π΅
}
fn cook_order() {}
}
ΠΠΎΠ»Ρ ΡΡΡΡΠΊΡΡΡ ΠΏΡΠΈΠ²Π°ΡΠ½Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. ΠΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΡΡΠΊΡΡΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎΠΉ Ρ pub
Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ Π΅Ρ ΠΏΠΎΠ»Ρ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌΠΈ - ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΏΠΎΠ»Π΅ Π½ΡΠΆΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ ΠΏΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΡΡΠΈ.
mod back_of_house {
pub struct Breakfast { // ΡΡΡΡΠΊΡΡΡΠ° ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½Π° ΠΊΠ°ΠΊ ΠΏΡΠ±Π»ΠΈΡΠ½Π°Ρ
pub toast: String, // ΠΏΠΎΠ»Π΅ ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½ΠΎ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ
seasonal_fruit: String, // ΠΏΠΎΠ»Π΅ ΠΎΡΡΠ°Π»ΠΎΡΡ ΠΏΡΠΈΠ²Π°ΡΠ½ΡΠΌ
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
} } } }
pub fn eat_at_restaurant() {
// ΠΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΠ΅Π· ΡΡΠ½ΠΊΡΠΈΠΈ ΠΊ ΡΡΡΡΠΊΡΡΡΠ΅ Ρ ΠΏΡΠΈΠ²Π°ΡΠ½ΡΠΌ ΠΏΠΎΠ»Π΅ΠΌ
// Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ:
let mut meal = back_of_house::Breakfast::summer("Rye");
// Π·Π°ΠΏΠΈΡΡ Π² ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅:
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
// Π΅ΡΠ»ΠΈ ΡΠ°ΡΠΊΠΎΠΌΠΌΠ΅Π½ΠΈΡΠΎΠ²Π°ΡΡ ΡΡΡΠΎΠΊΡ Π΄Π°Π»Π΅Π΅, Π±ΡΠ΄Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠ° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ:
// meal.seasonal_fruit = String::from("blueberries");
}
ΠΠΎΠ»Ρ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½ΠΈΠΉ ΠΏΡΠ±Π»ΠΈΡΠ½Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. ΠΠΎΡΡΠ°ΡΠΎΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ°ΠΌΠΎ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ pub enum
, ΡΡΠΎΠ±Ρ Π²ΠΈΠ΄Π΅ΡΡ Π²ΡΠ΅ Π΅Π³ΠΎ ΠΏΠΎΠ»Ρ.
mod back_of_house {
pub enum Appetizer { // ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°Π΅ΠΌ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ
Soup,
Salad,
} }
pub fn eat_at_restaurant() {
let order1 = back_of_house::Appetizer::Soup;
let order2 = back_of_house::Appetizer::Salad;
}
Π‘ ΠΏΠΎΠΌΠΎΡΡΡ as
ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΠ»ΡΠΊ Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡ Π² ΡΡΡΠΎΠΊΠ΅ Ρ use
. ΠΡΠΎΠ±Π΅Π½Π½ΠΎ ΡΡΠΎ ΡΠ΄ΠΎΠ±Π½ΠΎ Π² ΡΠ»ΡΡΠ°Π΅, ΠΊΠΎΠ³Π΄Π° Π½ΡΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΠΊ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΠΌ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌ Π² ΡΠ°Π·Π½ΡΡ
ΠΌΠΎΠ΄ΡΠ»ΡΡ
:
use std::fmt::Result;
use std::io::Result as IoResult; // IoResult - ΡΡΠ»ΡΠΊ Π½Π° ΡΠΈΠΏ Result Π² ΠΌΠΎΠ΄ΡΠ»Π΅ io
fn function1() -> Result {
// ... }
fn function2() -> IoResult<()> {
// ... }
ΠΡΠΈ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΈ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ use
, ΡΠ°ΠΌ ΡΡΠ»ΡΠΊ ΡΡΠΎΡ ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ ΠΏΡΠΈΠ²Π°ΡΠ½ΡΠΌ - ΡΠ΅ΡΠ΅Π· Π½Π΅Π³ΠΎ ΠΌΠΎΠ³ΡΡ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ scope. ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ
ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΌΠΎΠ³Π»ΠΈ ΡΠΎΠΆΠ΅ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΡΠ΅ΡΠ΅Π· ΡΡΠΎΡ ΡΡΠ»ΡΠΊ, Π½ΡΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ Π΅Π³ΠΎ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ:
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
} }
pub use crate::front_of_house::hosting; // ΡΠ΅-ΡΠΊΡΠΏΠΎΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°
pub fn eat_at_restaurant() {
hosting::add_to_waitlist(); // ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ΅ΡΠ΅Π· ΡΡΠ»ΡΠΊ
}
ΠΠ½Π΅ΡΠ½ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π²ΠΊΠ»ΡΡΠ°ΡΡΡΡ Π² ΡΠ°ΠΉΠ» Cargo.toml. ΠΠ°Π»Π΅Π΅, ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΈΠ· Π½ΠΈΡ
Π·Π°Π½ΠΎΡΡΡΡΡ Π² scope Ρ ΠΏΠΎΠΌΠΎΡΡΡ use
.
# Cargo.toml
rand = "0.8.5"
use rand::Rng;
fn main() {
let secret_number = rand::thread_rng().gen_range(1..=100);
}
ΠΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ Π²Π½Π΅ΡΡΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠΊΡΠ°ΡΠΈΡΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ use
:
//use std::cmp::Ordering;
//use std::io;
use std::{cmp::Ordering, io}; // ΡΠΏΠΈΡΠΎΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΎΡ ΠΎΠ±ΡΠ΅Π³ΠΎ ΠΊΠΎΡΠ½Ρ
//use std::io;
//use std::io::Write;
use std::io{self, Write}; // Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅Π³ΠΎ ΠΊΠΎΡΠ½Ρ Π² scope
use std::collections::*; // Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ
ΠΏΡΠ±Π»ΠΈΡΠ½ΡΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΏΠΎ ΠΏΡΡΠΈ
Π‘Π»Π΅Π΄ΡΠ΅Ρ Π±ΡΡΡ ΠΎΡΡΠΎΡΠΎΠΆΠ½ΡΠΌ Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠΎΠΌ glob - *
, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΡΠΎ Π²Π½Π΅ΡΡΠ½Π½ΡΠ΅ Ρ Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠ»ΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ, Π³Π΄Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΎΠ½ΠΈ Π±ΡΠ»ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ.
ΠΠ±ΡΡΠ²Π»Π΅Π½Π½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ, ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½Π½Π°Ρ ΠΏΠ°ΠΌΡΡΡΡ ΠΊΡΡΠΈ (heap) - ΠΎΠ±ΡΠ΅ΠΉ ΠΏΠ°ΠΌΡΡΡΡ (Π½Π΅ ΡΡΠ΅ΠΊΠ°!) Π²ΡΠ΅Π³Π΄Π° ΠΈΠΌΠ΅Π΅Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°. ΠΡΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅ ΡΠ°ΠΊΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π² Π΄ΡΡΠ³ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ, Π»ΠΈΠ±ΠΎ Π² ΡΡΠ½ΠΊΡΠΈΡ, ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ = ΡΠΌΠ΅Π½Π° Π²Π»Π°Π΄Π΅Π»ΡΡΠ°. ΠΠΎΡΠ»Π΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΡ, Π½Π΅Π»ΡΠ·Ρ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΠΊ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ.
let s1 = String::from("hello"); // ΡΡΡΠΎΠΊΠ° Π² ΠΊΡΡΠ΅ ΡΠΎΠ·Π΄Π°Π½Π° ΠΈΠ· Π»ΠΈΡΠ΅ΡΠ°Π»ΠΎΠ² Π² ΡΡΠ΅ΠΊΠ΅
let s2 = s1; // ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅
println!("{}, world!", s1); // ΠΎΡΠΈΠ±ΠΊΠ°! ΠΡΠ·ΠΎΠ² ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΡΠ½Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ
Π Π΅ΡΠ΅Π½ΠΈΡ:
let s1 = String::from("hello");
let s2 = s1.clone(); // ΠΏΠΎΠ»Π½ΡΠΉ ΠΊΠ»ΠΎΠ½. ΠΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΈ Π·Π°ΡΡΠ°ΡΠ½ΠΎ,
println!("s1 = {}, s2 = {}", s1, s2); // Π½ΠΎ Π½Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π²Π»Π°Π΄Π΅Π½ΠΈΡ
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1); // ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° ΡΡΡΠ»ΠΊΠΈ Π½Π° ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize { // ΠΏΡΠΈΡΠΌ ΡΡΡΠ»ΠΊΠΈ Π½Π° ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ
s.len()
}
ΠΠ»Ρ Π²Π½Π΅ΡΠ΅Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅ Π½Π° ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ, Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΡΡΠΎ ΡΠ²Π½ΠΎ ΡΠ΅ΡΠ΅Π· ‘mut’.
fn main() {
let mut s = String::with_capacity(32); // ΠΎΠ±ΡΡΠ²ΠΈΡΡ ΡΠ°Π·ΠΌΠ΅Ρ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½ΡΡ
Π·Π°ΡΠ°Π½Π΅Π΅, ΡΡΠΎΠ±Ρ ΠΏΠΎΡΠΎΠΌ Π½Π΅ Π΄ΠΎΠ²ΡΠ΄Π΅Π»ΡΡΡ ΠΏΡΠΈ Π·Π°ΠΊΠΈΠ΄ΡΠ²Π°Π½ΠΈΠΈ Π΄Π°Π½Π½ΡΡ
Π² ΡΡΡΠΎΠΊΡ = Π±ΡΡΡΡΠ΅Π΅
change(&mut s); // ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΠΉ ΡΡΡΠ»ΠΊΠΈ
}
fn change(some_string: &mut String) { // ΠΏΡΠΈΡΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΠΉ ΡΡΡΠ»ΠΊΠΈ Π½Π° ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ
some_string.push_str("hello, world");
}
ΠΡΠ°Π²ΠΈΠ»Π°:
let mut s = String::from("hello");
{
let r1 = &mut s;
} // r1 Π²ΡΡΠ»Π° ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ ΠΆΠΈΠ·Π½ΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΡΡ Π½ΠΎΠ²ΡΡ ΡΡΡΠ»ΠΊΡ Π½Π° ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ.
let r2 = &mut s;
ΠΠ½Π΅ΡΠ½ΡΡ ΡΡΡΠ»ΠΊΠ°: https://docs.rs/regex/latest/regex/
. any character except new line (includes new line with s flag)
[0-9] any ASCII digit
\d digit (\p{Nd})
\D not digit
\pX Unicode character class identified by a one-letter name
\p{Greek} Unicode character class (general category or script)
\PX Negated Unicode character class identified by a one-letter name
\P{Greek} negated Unicode character class (general category or script)
[xyz] A character class matching either x, y or z (union).
[^xyz] A character class matching any character except x, y and z.
[a-z] A character class matching any character in range a-z.
[[:alpha:]] ASCII character class ([A-Za-z])
[[:^alpha:]] Negated ASCII character class ([^A-Za-z])
[x[^xyz]] Nested/grouping character class (matching any character except y and z)
[a-y&&xyz] Intersection (matching x or y)
[0-9&&[^4]] Subtraction using intersection and negation (matching 0-9 except 4)
[0-9--4] Direct subtraction (matching 0-9 except 4)
[a-g~~b-h] Symmetric difference (matching `a` and `h` only)
[\[\]] Escaping in character classes (matching [ or ])
[a&&b] An empty character class matching nothing
x* zero or more of x (greedy)
x+ one or more of x (greedy)
x? zero or one of x (greedy)
x*? zero or more of x (ungreedy/lazy)
x+? one or more of x (ungreedy/lazy)
x?? zero or one of x (ungreedy/lazy)
x{n,m} at least n x and at most m x (greedy)
x{n,} at least n x (greedy)
x{n} exactly n x
x{n,m}? at least n x and at most m x (ungreedy/lazy)
x{n,}? at least n x (ungreedy/lazy)
x{n}? exactly n x
ΠΠ°Π΄Π°ΡΠ° Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΡΡΡΠΎΠΊΠΈ, ΡΠ°Π·Π΄Π΅Π»ΡΠ½Π½ΡΠ΅ - ΠΈΠ»ΠΈ _ Π½Π° CamelCase. ΠΡΠΈ ΡΡΠΎΠΌ Π΅ΡΠ»ΠΈ ΡΡΡΠΎΠΊΠ° Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ Ρ Π·Π°Π³Π»Π°Π²Π½ΠΎΠΉ Π±ΡΠΊΠ²Ρ, ΡΠΎ ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ Π½ΠΎΠ²ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΡΠΎΠΆΠ΅ Ρ Π½Π΅Ρ Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ:
"the-stealth-warrior" => "theStealthWarrior"
"The_Stealth_Warrior" => "TheStealthWarrior"
"The_Stealth-Warrior" => "TheStealthWarrior"
Π Π΅ΡΠ΅Π½ΠΈΠ΅:
use regex::Regex;
fn to_camel_case(text: &str) -> String {
let before = text;
let re = Regex::new(r"(-|_)(?P<neme>[A-z])").unwrap();
let after = re.replace_all(before,|captures: ®ex::Captures| {
captures[2].to_uppercase()
});
return after.to_string();
}
Π‘ΡΠ°ΡΡΡ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ°ΠΌ Π½Π° ΠΏΠ°ΠΌΡΡΡ Π² Rust
Π’ΠΈΠΏ Π΄Π°Π½Π½ΡΡ Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ΅ΠΌ. ΠΠΌΠ΅Π΅Ρ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ, Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠΉ Π² ΠΌΠΎΠΌΠ΅Π½Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ. ΠΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ Π²Π΅ΠΊΡΠΎΡΠ½ΡΡ ΡΡΡΡΠΊΡΡΡΡ:
pub struct String {
vec: Vec<u8>;
}
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΡΡΠΊΡΡΡΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Vec, ΡΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ Π΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΌΠ°ΡΡΠΈΠ² ΠΏΠ°ΠΌΡΡΠΈ, ΡΠ°Π·ΠΌΠ΅Ρ ΡΡΡΠΎΠΊΠΈ size ΡΡΡΡΠΊΡΡΡΡ ΠΈ ΡΠΌΠΊΠΎΡΡΡ capacity (ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊ ΡΡΡΠΎΠΊΠ΅ ΠΏΠ΅ΡΠ΅Π΄ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎΠ΄ ΡΡΡΠΎΠΊΡ).
Π‘ΡΡΠ»ΠΊΠ° Π½Π° String. ΠΠ΅ ΠΈΠΌΠ΅Π΅Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°, ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½, ΠΈΠ·Π²Π΅ΡΡΠ΅Π½ Π² ΠΌΠΎΠΌΠ΅Π½Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ.
fn change(mystring: &mut String) {
if !mystring.ends_with("s") {
mystring.push_str("s"); // Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ "s" Π² ΠΊΠΎΠ½Π΅Ρ ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ
}
ΠΠ°Π±ΠΎΡ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² (Π»ΠΈΡΠ΅ΡΠ°Π»ΠΎΠ²), ΡΠ°Π·ΠΌΠ΅ΡΡΠ½Π½ΡΡ Π½Π° ΡΡΠ΅ΠΊΠ΅. ΠΠ΅ ΠΈΠΌΠ΅Π΅Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°, ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½, ΠΈΠ·Π²Π΅ΡΡΠ΅Π½ Π² ΠΌΠΎΠΌΠ΅Π½Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ. ΠΠΎΠΆΠ½ΠΎ ΠΏΡΠ΅Π²ΡΠ°ΡΠ°ΡΡ str Π² String ΡΠ΅ΡΠ΅Π· ΠΏΡΠΈΠ·Π½Π°ΠΊ from:
let text = String::from("TEST"); // "TEST" :str
Π‘ΡΡΠ»ΠΊΠ° Π½Π° ΡΠ°ΡΡΡ, slice ΠΎΡ String (ΠΊΡΡΠ°), str (ΡΡΠ΅ΠΊ) ΠΈΠ»ΠΈ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ. ΠΠ΅ ΠΈΠΌΠ΅Π΅Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°, ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½, ΠΈΠ·Π²Π΅ΡΡΠ΅Π½ Π² ΠΌΠΎΠΌΠ΅Π½Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ.
fn main() {
let s = "hello_world";
let mut mut_string = String::from("hello");
success(&mutable_string);
fail(s);
}
fn success(data: &str) { // Π½Π΅ΡΠ²Π½ΡΠΉ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ &String -> &str
println!("{}", data);
}
fn fail(data: &String) { // ΠΠ¨ΠΠΠΠ - expected &String, but found &str
println!("{}", data);
}
ΠΠΎΠΊΠ° ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ &str Π΅Ρ Π² ΠΎΠ±Π»Π°ΡΡΠΈ ΠΆΠΈΠ·Π½ΠΈ Π½Π΅Π»ΡΠ·Ρ ΠΌΠ΅Π½ΡΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΏΠ°ΠΌΡΡΠΈ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠ½Π° ΡΡΡΠ»Π°Π΅ΡΡΡ, Π΄Π°ΠΆΠ΅ Π²Π»Π°Π΄Π΅Π»ΡΡΠ΅ΠΌ ΡΡΡΠΎΠΊΠΈ.
const CONST_STRING: &'static str = "a constant string";Β
ΠΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ String, Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΡΡΡΠ»ΠΊΡ &mut String Π΄Π»Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ:
fn main() {
let mut mutable_string = String::from("hello ");
do_mutation(&mut mutable_string);
println!("{}", mutables_string); // hello world!
}
fn do_mutation(input: &mut String) {
input.push_str("world!");
}
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ String Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅ΠΉ Π²Π»Π°Π΄Π΅Π½ΠΈΡ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ ΡΡΡΠΎΠΊΠΈ ΠΎΡ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° Π² ΠΏΠΎΡΠΎΠΊ (thread):
fn main() {
let s = "hello_world";
println!("{}", do_upper(s)); // HELLO_WORLD
}
fn do_upper(input: &str) -> String { // Π²ΠΎΠ·Π²ΡΠ°Ρ String
input.to_ascii_uppercase()
}
ΠΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π²Π»Π°Π΄Π΅Π»ΡΡΠ° Π½Π΅ Π½ΡΠΆΠ½ΠΎ, ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ Π² &str:
let s = String::from("Hello World!");
let word = first_word(&s);
println!("The first word is: {}", word);
}
fn first_word(s: &String) -> &str { // ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° ΡΡΡΠΎΠΊΠΈ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅
let word_count = s.as_bytes();
for (i, &item) in word_count.iter().enumerate() {
if item == b' ' {
return &s[..i]; // Π²ΠΎΠ·Π²ΡΠ°Ρ ΡΠ°ΡΡΠΈ ΡΡΡΠΎΠΊΠΈ ΠΊΠ°ΠΊ &str
}
}
&s[..] // ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π΅ΡΠ»ΠΈ ΡΡΠ»ΠΎΠ²ΠΈΠ΅ Π² ΡΠΈΠΊΠ»Π΅ Π²ΡΡΠ΅ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ Π²Π΅ΡΠ½ΡΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΡΠΎΠΊΠ° Π½Π΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΡΠΎΠ±Π΅Π»ΠΎΠ² = Π²Π΅ΡΠ½ΡΡΡ Π²ΡΡ ΡΡΡΠΎΠΊΡ)
ΠΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΠΉΡΠΈ ΠΏΠΎ ΡΡΡΠΎΠΊΠ΅ ΠΈΡΠ΅ΡΠ°ΡΠΎΡΠΎΠΌ chars() ΠΈ Π΅Π³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ Π²Π·ΡΡΠΈΡ N-Π³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° nth() ΡΠΏΠ΅ΡΠ΅Π΄ΠΈ ΠΈΠ»ΠΈ nth_back() ΡΠ·Π°Π΄ΠΈ:
let person_name = String::from("Alice");
println!("The last character of string is: {}", match person_name.chars().nth_back(0) { // ΠΈΡΠ΅ΠΌ 1-ΡΠΉ ΡΠΈΠΌΠ²ΠΎΠ» Ρ ΠΊΠΎΠ½ΡΠ° ΡΡΡΠΎΠΊΠΈ
Some(i) => i.to_string(), // Π΅ΡΠ»ΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌ - ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Π΅ΠΌ Π² ΡΡΡΠΎΠΊΡ
None => "Nothing found!".to_string(), // Π½Π΅ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌ = ΡΠΎΠΎΠ±ΡΠ°Π΅ΠΌ
});
// println!("Hello there!\n");
// ΡΠ°ΡΠΊΡΡΠ²Π°Π΅ΡΡΡ Π² ΡΠ°ΠΊΠΎΠΉ ΠΊΠΎΠ΄:
use std::io::{self, Write};
io::stdout().lock().write_all(b"Hello there!\n").unwrap();
fn main() {
let mut a = String::from("Wonderful RUST World");
println!("Hello{}!", output_string(&a)); // Π²ΡΠ²ΠΎΠ΄ ΡΡΡΠΎΠΊΠΈ
println!("String is empty? {}", a.is_empty());
println!("String length: {}", a.len());
println!("Does string contain 'Hello'? {}", a.contains("Hello"));
println!("{}",a.replace("RUST","Python")); // Wonderful Python World
for i in a.split_whitespace() {
println!("{}", i);
}
a.push_str(" And let's go!");
println!("{}",a);
}
fn output_string(t: &String) -> String {
format!(", {}",t) // Π²ΠΎΠ·Π²ΡΠ°Ρ ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ
}
ΠΠΎΠ²ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ std::repeat
fn main() {
let repeated = "Repeat".repeat(4);
println!("{}", repeated); // RepeatRepeatRepeatRepeat
}
Π‘ΡΠ°ΡΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΡΠ΅ΡΠ΅Π· ΠΈΡΠ΅ΡΠ°ΡΠΎΡ - ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎ ΠΎΡΠ΄Π°Π²Π°ΡΡ Π»ΡΠ±ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ (ΠΊΠ°ΠΊ generic):
use std::iter;
fn main() {
let repeated: String = iter::repeat("Repeat").take(4).collect();
println!("{}", repeated);
}
ΠΡΠ»ΠΈ ΡΡΡΡΠΊΡΡΡΠ΅ Π½Π°Π΄ΠΎ Π²Π»Π°Π΄Π΅ΡΡ ΡΠ²ΠΎΠΈΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ - ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ String. ΠΡΠ»ΠΈ Π½Π΅Ρ, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ &str, Π½ΠΎ Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ (lifetime), ΡΡΠΎΠ±Ρ ΡΡΡΡΠΊΡΡΡΠ° Π½Π΅ ΠΏΠ΅ΡΠ΅ΠΆΠΈΠ»Π° Π²Π·ΡΡΡΡ Π΅ΠΉ ΡΡΡΠΎΠΊΡ:
struct Owned {
bla: String,
}
struct Borrowed<'a> {
bla: &'a str,
}
fn main() {
let o = Owned {
bla: String::from("bla"),
};
let b = create_something(&o.bla);
}
fn create_something(other_bla: &str) -> Borrowed {
let b = Borrowed { bla: other_bla };
b // ΠΏΡΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅ Borrowed, ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π²ΡΡ Π΅ΡΡ Π² ΠΎΠ±Π»Π°ΡΡΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ!
}
ΠΠΎΠΆΠ½ΠΎ Π΄Π΅Π»ΠΈΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° split(). Π ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»ΠΈΡΡ ΠΏΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌ ΡΠΈΠΌΠ²ΠΎΠ»Π°ΠΌ ΡΠ°Π·ΠΎΠΌ:
let text = String::from("the_stealth-warrior");
let parts = text2.split(['-', '_']);
for part in parts {
println!("{}", part);
Π§ΡΠΎΠ±Ρ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ 1-ΡΡ Π±ΡΠΊΠ²Ρ Π² ΡΡΡΠΎΠΊΠ΅ (Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ ΠΈΠ΅ΡΠΎΠ³Π»ΠΈΡ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π°Π»ΡΠ°Π²ΠΈΡΠ°), Π½ΡΠΆΠ½ΠΎ ΡΡΡΠΎΠΊΡ ΠΏΠ΅ΡΠ΅Π΄Π΅Π»Π°ΡΡ Π² Π²Π΅ΠΊΡΠΎΡ ΠΈΠ· Π±ΡΠΊΠ²:
let char_vec: Vec<char> = text.chars().collect();
if char_vec[0].is_lowercase() { .. }
ΠΡΠΎΠ²Π΅ΡΠΊΡ Π½ΡΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°ΡΡ Π² Π²ΠΈΠ΄Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ:
fn is_vowel(c: char) -> bool {
c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' }
let text = String::from("Aria");
ΠΠ°Π½Π° ΡΡΡΠΎΠΊΠ° Ρ ΠΏΡΠΎΠ±Π΅Π»Π°ΠΌΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ»ΠΎΠ²Π°ΠΌΠΈ. ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ°Π·Π²Π΅ΡΠ½ΡΡΡ ΡΠ»ΠΎΠ²Π° Π² ΡΡΡΠΎΠΊΠ΅ Π½Π°ΠΎΠ±ΠΎΡΠΎΡ, ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΏΡΠΎΠ±Π΅Π»Ρ.
fn reverse_words_split(str: &str) -> String {
str.to_string()
.split(" ") // ΠΏΡΠΈ ΡΠ°Π·Π΄Π΅Π»Π΅Π½ΠΈΠΈ split() ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΡΠΎΠ±Π΅Π»Ρ ΡΠΎΡ
ΡΠ°Π½ΡΡΡΡΡ
.map(|x| x.chars().rev().collect::<String>()) // ΡΠ°Π·Π²ΠΎΡΠΎΡ ΡΠ»ΠΎΠ²+ΡΠ±ΠΎΡ Π² ΡΡΡΠΎΠΊΡ
.collect::<Vec<String>>(). // ΡΠ±ΠΎΡ Π²ΡΠ΅Π³ΠΎ Π² Π²Π΅ΠΊΡΠΎΡ
.join(" ") // ΠΏΡΠ΅Π²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ Π²Π΅ΠΊΡΠΎΡΠ° Π² ΡΡΡΠΎΠΊΡ
}
fn main() {
let word: &str = "The quick brown fox jumps over the lazy dog.";
println!("{}",reverse_words_split(&word));
}
// ehT kciuq nworb xof spmuj revo eht yzal .god
Π ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ Π²Π΅ΠΊΡΠΎΡ ΠΈΠ· ΡΡΡΠΎΠΊ. ΠΠ°Π»Π΅Π΅, Π°Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ Π΅Π³ΠΎ ΠΏΠΎ ΡΠ°ΡΡΡΠΌ:
fn likes(names: &[&str]) -> String {
match names {
[] => "no one likes this".to_string(),
[a] => format!("{} likes this", a),
[a, b] => format!("{} and {} like this", a, b),
[a, b, c] => format!("{}, {} and {} like this", a, b, c),
[a, b, other @ ..] => format!("{}, {} and {} others like this", a, b, other.len()),
}
}
Use split(' ')
, filter out empty entries then re-join by space:
s.trim()
.split(' ')
.filter(|s| !s.is_empty())
.collect::<Vec<_>>()
.join(" ")
// Using itertools:
use itertools::Itertools;
s.trim().split(' ').filter(|s| !s.is_empty()).join(" ")
// Using split_whitespace, allocating a vector & string
pub fn trim_whitespace_v1(s: &str) -> String {
let words: Vec<_> = s.split_whitespace().collect();
words.join(" ")
}
Struct - ΠΊΠΎΠΌΠΏΠ»Π΅ΠΊΡΠ½ΡΠΉ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡΠΉ ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ , ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅ΡΡΡ Π² ΠΊΡΡΠ΅ (heap), ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π²Π½ΡΡΡΠΈ ΡΠ΅Π±Ρ ΡΠ°Π·Π½ΡΠ΅ ΡΠΈΠΏΡ Π΄Π°Π½Π½ΡΡ . ΠΠ½ ΠΏΠΎΡ ΠΎΠΆ Π½Π° ΠΊΠΎΡΡΠ΅ΠΆ (tuple), ΠΎΠ΄Π½Π°ΠΊΠΎ ΡΠΈΠΏΡ Π΄Π°Π½Π½ΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΠΌΠ΅ΡΡ ΡΠ²Π½ΡΠ΅ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΡ.
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64, // Π·Π°ΠΏΡΡΠ°Ρ Π² ΠΊΠΎΠ½ΡΠ΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½Π°
}
ΠΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ struct Π² ΡΡΠ½ΠΊΡΠΈΡ ΠΈΠ»ΠΈ Π²Π΅ΡΠ½ΡΡΡ ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ:
fn main() {
// ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΡΠ΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΏΠΎ ΡΡΡΡΠΊΡΡΡΠ΅ Π΄Π°Π½Π½ΡΡ
Π²ΡΡΠ΅
let mut user1 = create_user(String::from("john@doe.com"), String::from("testuser"));
println!("User Email is {}", user1.email);
user1.email = String::from("Parker@doe.com");
println!("User Email is {}", user1.email);
}
fn create_user(email: String, username: String) -> User { // Π²ΠΎΠ·Π²ΡΠ°Ρ ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ
User {
active: true,
username,
email,
// ΠΈΠΌΠ΅Π½Π° ΠΏΠΎΠ»Π΅ΠΉ ΠΈΠΌΠ΅ΡΡ Ρ Π²Ρ
ΠΎΠ΄Π½ΡΠΌΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ, ΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ ΠΏΠΈΡΠ°ΡΡ username: username, email: email.
sign_in_count: 1,
} // return Π·Π°ΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΎΡΡΡΡΡΡΠ²ΠΈΠ΅ΠΌ Π·Π½Π°ΠΊΠ° ";"" ΠΊΠ°ΠΊ ΠΎΠ±ΡΡΠ½ΠΎ
}
ΠΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ Π½ΠΎΠ²ΡΡ ΡΡΡΡΠΊΡΡΡΡ ΠΏΠΎ ΠΏΠΎΠ΄ΠΎΠ±ΠΈΡ ΡΡΠ°ΡΠΎΠΉ, ΠΈ Π±ΠΎΠ»ΡΡΠ°Ρ ΡΠ°ΡΡΡ ΠΏΠΎΠ»Π΅ΠΉ Ρ Π½ΠΈΡ ΠΏΠΎΡ ΠΎΠΆΠΈ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°Ρ Π°Ρ:
let user2 = User {
email: String::from("another@example.com"), // Π·Π°Π΄Π°ΡΡ Π½ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Ρ
..user1 // Π²Π·ΡΡΡ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ Π°ΡΡΠΈΠ±ΡΡΡ ΠΈΠ· user1. ΠΠ΄ΡΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ Π·Π°ΠΏΠΈΡΡΡ
};
Π‘ΡΡΡΠΊΡΡΡΡ ΡΠ°ΠΊΠΎΠ³ΠΎ Π²ΠΈΠ΄Π° ΠΏΠΎΡ ΠΎΠΆΠΈ Π½Π° ΠΊΠΎΡΡΠ΅ΠΆΠΈ, Π½ΠΎ ΠΈΠΌΠ΅ΡΡ ΠΈΠΌΡ ΡΡΡΡΠΊΡΡΡΡ ΠΈ ΡΠΈΠΏ. ΠΡΠΆΠ½Ρ, ΠΊΠΎΠ³Π΄Π° Π½ΡΠΆΠ½ΠΎ Π²ΡΠ΄Π΅Π»ΠΈΡΡ ΠΊΠΎΡΡΠ΅ΠΆ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌ ΡΠΈΠΏΠΎΠΌ, Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ³Π΄Π° Π½Π°Π΄ΠΎ Π΄Π°ΡΡ ΠΎΠ±ΡΠ΅Π΅ ΠΈΠΌΡ ΠΊΠΎΡΡΠ΅ΠΆΡ. ΠΡΠΈ ΡΡΠΎΠΌ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΠΏΠΎΠ»Ρ Π½Π΅ ΠΈΠΌΠ΅ΡΡ ΠΈΠΌΡΠ½.
struct Color (i32, i32, i32);
struct Point (i32, i32, i32);
fn main() {
let red = Color(255,0,0);
let origin = Point(0, 0, 0);
ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ red ΠΈ origin ΡΠ°Π·Π½ΡΡ ΡΠΈΠΏΠΎΠ². Π€ΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±Π΅ΡΡΡ Color ΠΊΠ°ΠΊ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ, Π½Π΅ Π²ΠΎΠ·ΡΠΌΡΡ Point, Π½Π΅ΡΠΌΠΎΡΡΡ Π½Π° ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΠ΅ ΡΠΈΠΏΡ Π²Π½ΡΡΡΠΈ. ΠΠ°ΠΆΠ΄Π°Ρ ΡΡΡΡΠΊΡΡΡΠ° = ΡΠ²ΠΎΠΉ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΠΈΠΏ. Π Π°Π·Π±ΠΎΡ ΡΠ°ΠΊΠΈΡ ΡΡΡΡΠΊΡΡΡ Π½Π° ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ΅Π½ ΠΊΠΎΡΡΠ΅ΠΆΠ°ΠΌ.
let (x,y,z) = (origin.0,origin.1,origin.2);
Π‘ΡΡΡΠΊΡΡΡΡ Π±Π΅Π· ΠΏΠΎΠ»Π΅ΠΉ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Ρ ΠΊΠΎΡΡΠ΅ΠΆΠ°ΠΌ Π±Π΅Π· ΠΏΠΎΠ»Π΅ΠΉ, ΡΠΎΠ»ΡΠΊΠΎ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ.
struct TestTrait;
fn main() {
test = TestTrait;
}
Π’Π°ΠΊΠΈΠ΅ ΡΡΡΡΠΊΡΡΡΡ Π½ΡΠΆΠ½Ρ Π΄Π»Ρ Π·Π°Π΄Π°Π½ΠΈΡ ΠΏΡΠΈΠ·Π½Π°ΠΊΠΎΠ² (traits), ΠΊΠΎΠ³Π΄Π° Π² ΡΠ°ΠΌΠΎΠΉ ΡΡΡΡΠΊΡΡΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Ρ ΡΠ°Π½ΠΈΡΡ Π½Π΅ Π½ΡΠΆΠ½ΠΎ.
ΠΠΎΠΆΠ½ΠΎ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠΌ ΠΏΠΎΠ»Π΅ΠΉ ΡΡΡΡΠΊΡΡΡΡ Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π° ΠΊΠΎΠ΄Π°. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π½Π°Π΄ ΡΡΡΡΠΊΡΡΡΠΎΠΉ ΠΏΠΎΠΌΠ΅ΡΠΊΡ debug:
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let scale = 2;
let rect = Rectangle {
width: dbg!(20 * scale), // Π²ΡΠ²ΠΎΠ΄ ΠΏΠΎΠ»Ρ ΡΡΡΡΠΊΡΡΡΡ. dbg! Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π½Π°Π·Π°Π΄
height: 10, // Π²Π·ΡΡΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Ρ Π½ΠΈΠΌ Π΄Π°Π»Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ
};
println!("Rectangle content: {:?}",rect); // Π²ΡΠ²ΠΎΠ΄ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΡΡΡΡΠΊΡΡΡΡ
dbg!(&rect); // Π΅ΡΡ Π²Π°ΡΠΈΠ°Π½Ρ Π²ΡΠ²ΠΎΠ΄Π° - Π² ΠΏΠΎΡΠΎΠΊ stderr. Π€ΡΠ½ΠΊΡΠΈΡ dbg!
// Π·Π°Π±ΠΈΡΠ°Π΅Ρ Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΡΡΡΡΠΊΡΡΡΠΎΠΉ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅
}
ΠΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΊΠ°ΠΊ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΏΡΠΈΠ²ΡΠ·Π°Π½Π½ΡΠ΅ ΠΊ ΡΡΡΡΠΊΡΡΡΠ°ΠΌ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠΊΠΎ - ΠΏΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌ ΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠΌ Π½Π°Π΄ Π½ΠΈΠΌΠΈ.
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle { // impl ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π±Π»ΠΎΠΊ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΡΡΡΡΠΊΡΡΡΡ Rectangle
fn area(&self, scale) -> u32 { // 1-ΡΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ Π²ΡΠ΅Π³Π΄Π° self = ΡΡΡΡΠΊΡΡΡΠ°
self.width * self.height * scale // ΡΠ΅Π»ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈ Π²ΠΎΠ·Π²ΡΠ°Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
} }
fn main() {
let rect = Rectangle {
width: 20,
height: 10,
};
println!("Rectangle area is {}", rect.area(2)); // Π²ΡΠ·ΠΎΠ² ΠΌΠ΅ΡΠΎΠ΄Π°
}
ΠΠ°ΠΊ ΠΈ Π²Π΅Π·Π΄Π΅, Π΄Π»Ρ Π²Π½Π΅ΡΠ΅Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² ΠΎΠ±ΡΠ΅ΠΊΡ ΡΡΡΡΠΊΡΡΡΡ, Π² Π±Π»ΠΎΠΊΠ΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΡΡ &mut self
, Π° Π΄Π»Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΡ Π²Π»Π°Π΄Π΅Π½ΠΈΡ - ΠΏΡΠΎΡΡΠΎ self
. ΠΡΠΎ Π½ΡΠΆΠ½ΠΎ ΠΈΠ·ΡΠ΅Π΄ΠΊΠ° ΠΏΡΠΈ ΠΏΡΠ΅Π²ΡΠ°ΡΠ΅Π½ΠΈΠΈ self Π² Π΄ΡΡΠ³ΠΎΠΉ Π²ΠΈΠ΄ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, Ρ ΡΠ΅Π»ΡΡ Π·Π°ΠΏΡΠ΅ΡΠΈΡΡ Π²ΡΠ·ΠΎΠ² ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΠ»ΠΎΠΊΠΎΠ² impl
ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ.
Π Π±Π»ΠΎΠΊΠ΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² impl
ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠ΅ΡΠ²ΡΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ Π½Π΅ Π±Π΅ΡΡΡ ΡΠ°ΠΌΡ ΡΡΡΡΠΊΡΡΡΡ self
. Π’Π°ΠΊΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π΅ ΡΠ²Π»ΡΡΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ ΠΈ ΡΠ°ΡΡΠΎ ΡΠ»ΡΠΆΠ°Ρ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π½ΠΎΠ²ΡΡ
Π²Π΅ΡΡΠΈΠΉ ΠΎΠ±ΡΠ΅ΠΊΡΠ°.
fn square(side: u32) -> Self { // Self - Π°Π»ΠΈΠ°Ρ Π΄Π»Ρ ΡΠΈΠΏΠ° Π΄Π°Π½Π½ΡΡ
Rectangle
Self {
width: side,
height: side,
} } }
fn main() {
let sq = Rectangle::square(10); // Π²ΡΠ·ΠΎΠ² Π°ΡΠΎΡΠΈΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ΅ΡΠ΅Π· ::
println!("Square created from {:?}",sq);
}
ΠΠΌΠ΅ΡΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π²Π²Π΅Π΄ΡΠ½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π½Π° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ Π²Π½ΡΡΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ , ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ Π² ΡΠ΅Π±Π΅ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΎΠ±ΡΡΠ²ΠΈΠΌ ΡΠΈΡΠ»ΠΎ ΠΎΡ 1 Π΄ΠΎ 100 Π΄Π»Ρ ΠΈΠ³ΡΡ, Π³Π΄Π΅ Π½Π°Π΄ΠΎ ΡΠ³Π°Π΄Π°ΡΡ ΡΠΈΡΠ»ΠΎ:
pub struct Guess { // ΠΎΠ±ΡΡΠ²ΠΈΠ»ΠΈ ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ
(ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ)
value: i32, // Π²Π½ΡΡΡΠΈ ΡΠΈΡΠ»ΠΎ (ΠΏΡΠΈΠ²Π°ΡΠ½ΠΎΠ΅)
}
impl Guess {
pub fn new(value: i32) -> Guess { // ΠΌΠ΅ΡΠΎΠ΄ new ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅
if value < 1 || value > 100 { // Π½Π° Π·Π°Π΄Π°Π½Π½ΡΠ΅ Π³ΡΠ°Π½ΠΈΡΡ 1-100
panic!("Guess value must be between 1 and 100, got {}.", value);
}
Guess { value } // Π²ΠΎΠ·Π²ΡΠ°Ρ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° Π΄Π°Π½Π½ΡΡ
}
pub fn value(&self) -> i32 { // ΠΌΠ΅ΡΠΎΠ΄ getter Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ value
self.value // ΠΎΠ½ Π½ΡΠΆΠ΅Π½, ΡΠΊ Π½Π°ΠΏΡΡΠΌΡΡ Π²ΠΈΠ΄Π΅ΡΡ value Π½Π΅Π»ΡΠ·Ρ
} // ΠΡΠΎ ΠΏΡΠΈΠ²Π°ΡΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π² ΡΡΡΡΠΊΡΡΡΠ΅.
}
ΠΠΎΡΠΎΠΊΠΈ - ΠΎΠ±ΡΠ΅ΠΊΡ ΠΠ‘, ΡΠΏΠΎΡΠΎΠ± ΡΠ°Π·Π΄Π΅Π»Π΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΠ. ΠΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΌΠΎΠ³ΡΡ Π½Π°Π·Π½Π°ΡΠ°ΡΡΡΡ ΡΠ°Π·Π½ΡΠ΅ ΡΠ΄ΡΠ°, Π° ΠΌΠΎΠ³ΡΡ ΠΈ Π½Π΅ Π½Π°Π·Π½Π°ΡΠ°ΡΡΡΡ. ΠΠΎΡΠΎΠΊΠΈ Π²ΡΠ³ΠΎΠ΄Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π΄Π°ΡΡ Π²ΡΠΈΠ³ΡΡΡ Π²ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π±ΠΎΠ»ΡΡΠ΅, ΡΠ΅ΠΌ Π²ΡΠ΅ΠΌΡ Π½Π° ΠΈΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ (Π½Π° x86 ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°Ρ = ~9000 Π½Π°Π½ΠΎΡΠ΅ΠΊ, Π½Π° ARM ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°Ρ = ~27000 Π½Π°Π½ΠΎΡΠ΅ΠΊ). ΠΠ±ΡΡΠ½ΠΎ, ΡΡΠΎ ΠΈΠ½ΡΠ΅Π½ΡΠΈΠ²Π½ΡΠ΅ ΠΏΠΎ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠ»Ρ ΠΈΠ½ΡΠ΅Π½ΡΠΈΠ²Π½ΡΠΌ ΠΏΠΎ Π²Π²ΠΎΠ΄Ρ-Π²ΡΠ²ΠΎΠ΄Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ async/await Π²ΠΌΠ΅ΡΡΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ².
ΠΡΠΈΠΌΠ΅Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ:
fn hello_thread() {
println!("Hello from thread")
}
fn main() {
println!("Hello from the MAIN thread");
let thread_handle = std::thread::spawn(hello_thread);
thread_handle.join().unwrap(); // Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡΡ Π½ΠΎΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ Ρ Π³Π»Π°Π²Π½ΡΠΌ
// ΠΏΠΎΡΠΎΠΊΠΎΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΈΠ½Π°ΡΠ΅ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ ΡΡΠΏΠ΅ΡΡ Π²Π΅ΡΠ½ΡΡΡ Π΄Π°Π½Π½ΡΠ΅ Π΄ΠΎ
// Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
}
ΠΠΎΡΠΎΠΊΠΈ ΡΠ²Π»ΡΡΡΡΡ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°ΠΌΠΈ Π΄Π°Π½Π½ΡΡ , ΠΏΠΎΡΡΠΎΠΌΡ Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΈΠΌ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ Π±ΡΠ»ΠΈ ΠΆΠΈΠ²Ρ ΠΊ ΠΌΠΎΠΌΠ΅Π½ΡΡ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΠΎΡΠΎΠΊΠ°:
fn do_math(i: u32) -> u32 {
let mut n = i + 1;
for _ in 0..10 {
n *= 2;
}
n
}
fn main() {
println!("Hello from the MAIN thread");
let mut thread_handles = Vec::new(); // Π²Π΅ΠΊΡΠΎΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΠΏΠΎΡΠΎΠΊΠΎΠ²
for i in 0..10 {
let thread_handle = std::thread::spawn(move || do_math(i));
thread_handles.push(thread_handle); // Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΏΠΎΡΠΎΠΊ ΠΊ Π²Π΅ΠΊΡΠΎΡ
}
for h in thread_handles.into_iter() {
println!("{}", h.join().unwrap()); // ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² Ρ Π³Π»Π°Π²Π½ΡΠΌ.
} // ΠΈ Π²ΡΠ²ΠΎΠ΄ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°.
ΠΡΠΎΡΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ - ΠΏΠΎΠ΄Π΅Π»ΠΈΡΡ Π²Π΅ΠΊΡΠΎΡ ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌΠΈ Π½Π° ΠΊΡΡΠΊΠΈ (chunks), ΠΈ ΠΏΠΎΠ΄ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΡΡΠΊΠ° ΡΠ΄Π΅Π»Π°ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΏΠΎΡΠΎΠΊ, ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ ΡΠΎΠ±ΡΠ°ΡΡ ΠΏΠΎΡΠΎΠΊΠΈ Π²ΠΌΠ΅ΡΡΠ΅:
fn main() {
const N_THREADS: usize = 8;
let to_add = (0..5000).collect::<Vec<u32>>(); // Π²Π΅ΠΊΡΠΎΡ ΠΎΡ 0 Π΄ΠΎ 4999
let mut thread_handles = Vec::new(); // Π²Π΅ΠΊΡΠΎΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΠΏΠΎΡΠΎΠΊΠΎΠ²
let chunks = to_add.chunks(N_THREADS); // ΡΠ°Π·ΠΌΠ΅Ρ ΠΊΡΡΠΊΠΎΠ² ΡΠ°Π·Π±ΠΈΠ΅Π½ΠΈΡ
for chunk in chunks {
let my_chunk = chunk.to_owned(); // ΠΎΠ±Ρ
ΠΎΠ΄ borrow checker/lifetime
thread_handles.push(std::thread::spawn(move || my_chunk.iter().sum::<u32>())); // ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² Ρ ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°ΡΠΈΠΌΠΈ ΠΈΠΌ Π΄Π°Π½Π½ΡΠΌΠΈ
}
// ΡΡΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ²-ΠΊΡΡΠΊΠΎΠ² Π² ΠΎΠ΄Π½ΠΎ ΡΠΈΡΠ»ΠΎ
let mut sum: u32 = 0;
for handle in thread_handles {
sum += handle.join().unwrap()
}
println!("Sum is {sum}");
}
Π’ΠΈΠΏΠ°ΠΆ Π½ΡΠΆΠ΅Π½ Π΄Π»Ρ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°: ΠΎΠ½ Π·Π°Π΄Π°ΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ-ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΡ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΈΠ»ΠΈ ΡΡΡΡΠΊΡΡΡ Ρ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΌΠΈ (generic) ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ. ΠΡ ΠΎΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ°ΠΆΠ° ΠΎΡ Π΅Π³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ. ΠΡΠΈ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠΈ ΡΠΈΠΏΠ°ΠΆΠ° ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΡΠ°Π²ΠΈΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π½Π° ΠΏΠΎΡΠΎΠΌ, Π»ΠΈΠ±ΠΎ Π²ΠΏΠΈΡΠ°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π² ΡΠΈΠΏΠ°ΠΆΠ΅ ΠΏΠΎ-ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ:
// ΡΠΈΠΏΠ°ΠΆ Π·Π°Π΄Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ ΠΏΠΎ Π²Ρ
ΠΎΠ΄Π½ΡΠΌ/Π²ΡΡ
ΠΎΠ΄Π½ΡΠΌ ΡΠΈΠΏΠ°ΠΌ
trait LandVehicle {
fn LandDrive(&self) -> String; }
// ΡΠΈΠΏΠ°ΠΆ Π·Π°Π΄Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΏΠ»ΡΡ ΠΈΡ
ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ
trait WaterVehicle {
fn WaterDrive(&self) { println!("Default float"); }
}
ΠΠΎ Π²ΡΠ΅ΠΌΡ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ, Π΅ΡΠ»ΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π±ΡΠ»Π° Π·Π°Π΄Π°Π½Π°, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π΅Π»Π°ΡΡ ΠΏΠΎΠ΄ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΡ ΡΡΡΡΠΊΡΡΡΡ, Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ:
struct Sedan {}
struct Rocketship {}
// ΡΠΈΠΏΠ°ΠΆ LandVehicle Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ, ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΡΡΡ
impl LandVehicle for Sedan {
fn LandDrive(&self) -> String { format!("Car zoom-zoom!") } }
// ΡΠΈΠΏΠ°ΠΆ WaterVehicle ΠΈΠΌΠ΅Π΅Ρ Π²ΡΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π΅Ρ
impl WaterVehicle for Rocketship {}
ΠΡΠΈ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΈ, ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΡΡΠ»ΡΠΊ (alias). ΠΡΠΈ ΡΡΠΎΠΌ ΠΊΠ°ΠΆΠ΄ΡΠΉ Π²Ρ ΠΎΠ΄ΡΡΠΈΠΉ Π² Π½Π΅Π³ΠΎ ΡΠΈΠΏΠ°ΠΆ Π½ΡΠΆΠ½ΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΠΊ ΡΡΡΡΠΊΡΡΡΠ΅ Π΄Π°Π½Π½ΡΡ . ΠΡΠΈ ΡΡΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΡ Π² ΡΠΈΠΏΠ°ΠΆΠ΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ, Π»ΠΈΠ±ΠΎ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ²ΠΎΡ.
// ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΡΠ»ΡΠΊΠ°
trait AmphibiousVehicle: LandVehicle + WaterVehicle {}
// ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ°ΠΆΠ΅ΠΉ ΠΊ ΡΡΡΡΠΊΡΡΡΠ΅
impl AmphibiousVehicle for Carrier {}
impl LandVehicle for Carrier {
fn LandDrive(&self) -> String { format!("Use air thrust to travel on land") }
}
impl WaterVehicle for Carrier {}
fn main() {
let toyota_camry = Sedan {};
println!("{}",toyota_camry.LandDrive());
let rs = Rocketship {};
rs.WaterDrive();
let project_x = Carrier {};
println!("{}",project_x.LandDrive());
project_x.WaterDrive();
}
When in doubt on variable type: just use i32
for everything! i32
is the default in Rust, and the fastest, even on x64 architecture.
Unsigned | Signed |
---|---|
u8 | i8 |
u16 | i16 |
u32 | i32 |
u64 | i64 |
u128 | i128 |
usize | isize |
Floating point vars: f32, f64. |
You can declare number variables with _
sign in any place for convenience:
let x: i32 = 1_000_000;
let (mut missiles: i32, ready: u32) = (8, 5); // 2 vars tuple assign in 1 line
You can also add the var type to the number (convenient with _
when using generics):
let x = 1000_u32;
let y = 3.14_f32;
String2Int:
let n_str = "123456789".to_string();
let n_int = n_str.parse::<i32>().unwrap();
Char2Int:
let letter = 'a';
println!("{}", letter as u32 - 96); // = 97-96 = 1
let i = 97u8; // ΡΠΎΠ»ΡΠΊΠΎ Ρ u8 ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΎ Π΄Π΅Π»Π°ΡΡ 'as char'
println!("Value: {}", i as char);
bool type can be true
or false
. Non-integer - do NOT try to use arithmetic on these. But you can cast them:
true as u8;
false as u8;
By default, variables in Rust are immutable. To make a variable mutable, special “mut” identifier must be placed. Rust compiler may infer the variable type from the type of value.
let x = 5; // immutable variable, type i32 guessed by Rust as default for numbers.
let mut x = 5; // mutable variable
Variable names can be reused. This is not mutability, because shadowing always re-creates the variable from scratch. Previous variable value may be used:
let x = 5;
let x = x + 1; // new variable created with value = 6
Constant values are always immutable and available in the scope they were created in throughout the whole program. Type of constant must always be defined. Constants may contain results of operations. They are evaluated by Rust compiler. List of evaluations: https://doc.rust-lang.org/stable/reference/const_eval.html
const ONE_DAY_IN_SECONDS: u32 = 24 * 60 * 60; // type u32 MUST be defined
let phrase = "Hello World";
println!("Before: {phrase}"); // Before: Hello World
let phrase = phrase.len();
println!("After: {phrase}"); // After: 11
Compound type, immutable, consists of different types.
let tup: (u32, f32, i32) = (10, 1.2, -32);
let (x,y,z) = tup; // tuple deconstructing into variables
let a1 = tup.0;
let a2 = tup.1; // another way to deconstruct values
Deconstructing tuples is very useful when a function returns a tuple:
let (left, right) = slice.split_at(middle);
let (_, right) = slice.split_at(middle); // use '_' to throw away part of return
Compound type, mutable, all values of the same type.
let ar: [i32;5] = [1,2,3,4,5];
// array data is allocated on the stack rather than the heap
// [i32;5] - type of values and number of elements
let first = ar[0];
let second = ar[1]; // accessing array elements
ΠΠΎΠ΄ΡΡΡΡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π² ΠΌΠ°ΡΡΠΈΠ²Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ itertools…
ΠΠ΅ΠΊΡΠΎΡ - ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π΄Π°Π½Π½ΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°, ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΊΠΎΡΠΎΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ: Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΈ ΡΠ΄Π°Π»ΡΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ. ΠΡΠΆΠ΅Π½, ΠΊΠΎΠ³Π΄Π°:
// ΠΠ°Π΄Π°Π½ΠΈΠ΅ ΠΏΡΡΡΠΎΠ³ΠΎ Π²Π΅ΠΊΡΠΎΡΠ°:
// let mut a test_vector: Vec<i32> = Vec::new();
// ΠΠ°Π΄Π°Π½ΠΈΠ΅ Π²Π΅ΠΊΡΠΎΡΠ° ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌΠΈ ΡΠ΅ΡΠ΅Π· ΠΌΠ°ΠΊΡΠΎΡ:
let mut test_vector = vec![1, 2, 3, 4];
test_vector.push(42); // Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠΈΡΠ»ΠΎ 42 Π² ΠΊΠΎΠ½Π΅Ρ mut Π²Π΅ΠΊΡΠΎΡΠ°
test_vector.remove(0); // ΡΠ΄Π°Π»ΠΈΡΡ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ =1
for i in &mut test_vector { // ΠΏΡΠΎΠΉΡΠΈ Π²Π΅ΠΊΡΠΎΡ ΠΊΠ°ΠΊ ΠΈΡΠ΅ΡΠ°ΡΠΎΡ Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π°
*i += 1; // ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΡΠΈ ΠΈΡ
ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ ΡΡΠ΅Π±ΡΠ΅Ρ Π΄Π΅Π»Π°ΡΡ '*' dereference
println!("{i}"); }
println!("Vector length: {}", test_vector.len()); // ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ²
ΠΠ»Π΅ΠΌΠ΅Π½Ρ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΈΠ½Π΄Π΅ΠΊΡΠ°, Π»ΠΈΠ±ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° get
:
let mut test_vector = vec![1,2,3,4,5];
println!("Third element of vector is: {}", &test_vector[2]); // ΠΈΠ½Π΄Π΅ΠΊΡ
let third: Option<&i32> = test_vector.get(2); // ΠΌΠ΅ΡΠΎΠ΄ get
match third {
Some(third) => println!("Third element of vector is: {}", third),
None => println!("There is no third element")
}
Π Π°Π·Π½ΠΈΡΠ° Π² ΡΠΏΠΎΡΠΎΠ±Π°Ρ
Π² ΡΠ΅Π°ΠΊΡΠΈΠΈ Π½Π° ΠΏΠΎΠΏΡΡΠΊΡ Π²Π·ΡΡΡ Π½Π΅ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π·Π° ΠΏΡΠ΅Π΄Π΅Π»Π°ΠΌΠΈ Π²Π΅ΠΊΡΠΎΡΠ°. ΠΠ·ΡΡΠΈΠ΅ ΡΠ΅ΡΠ΅Π· ΠΈΠ½Π΄Π΅ΠΊΡ ΠΏΡΠΈΠ²Π΅Π΄ΡΡ ΠΊ ΠΏΠ°Π½ΠΈΠΊΠ΅ ΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΠ·ΡΡΠΈΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ get
ΡΠΎΠΏΡΠΎΠ²ΠΎΠΆΠ΄Π°Π΅ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΎΠΉ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ.
Rust Π½ΡΠΆΠ½ΠΎ Π·Π°ΡΠ°Π½Π΅Π΅ Π·Π½Π°ΡΡ ΠΏΡΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π½ΡΠΆΠ½ΠΎ Π²ΡΠ΄Π΅Π»ΡΡΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎΠ΄ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ. ΠΡΠ»ΠΈ ΠΈΠ·Π²Π΅ΡΡΠ½Ρ Π·Π°ΡΠ°Π½Π΅Π΅ Π²ΡΠ΅ ΡΠΈΠΏΡ Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΠΉ enum:
#[derive(Debug)]
enum SpreadSheet {
Int(i32),
Float(f64),
Text(String)
}
fn main() {
let row = vec![
SpreadSheet::Int(42),
SpreadSheet::Float(3.14),
SpreadSheet::Text(String::from("red"))
];
for i in row {
println!("{:?}",i);
} }
let mut v: Vec<String> = Vec::new();
ΠΡΡΡΠΎΠΉ Π²Π΅ΠΊΡΠΎΡ Ρ Π½ΡΠ»Π΅Π²ΡΠΌΠΈ ΡΡΡΠΎΠΊΠ°ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ΅ΡΠ΅Π· Default ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ Π΄ΠΎ 32 ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² (Rust 1.47):
let v: [String; 32] = Default::default();
ΠΠ΅ΠΊΡΠΎΡ Π±ΠΎΠ»ΡΡΠ΅Π³ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ° ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Vec:
let mut v: Vec<String> = vec![String::new(); 100];
ΠΠ΅ΠΊΡΠΎΡ Ρ Π·Π°Π΄Π°Π½Π½ΡΠΌΠΈ ΡΡΡΠΎΠΊΠ°ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π»ΠΈΠ±ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° to_string(), Π»ΠΈΠ±ΠΎ ΡΠ΅ΡΠ΅Π· ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ°ΠΊΡΠΎΡΠ°:
macro_rules! vec_of_strings {
($($x:expr),*) => (vec![$($x.to_string()),*]);
}
fn main()
{
let a = vec_of_strings!["a", "b", "c"];
let b = vec!["a".to_string(), "b".to_string(), "c".to_string()];
assert!(a==b); // True
}
Π‘ΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π²Π΅ΠΊΡΠΎΡΠ° ΡΠΎ ΡΡΡΠΎΠΊΠ°ΠΌΠΈ Π² ΡΡΡΠΎΠΊΡ (Join):
result_vec.join(" "); // ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΠ΅Π»Ρ Π΄Π»Ρ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ
// Π² ΡΡΠ°ΡΡΡ
Π²Π΅ΡΡΠΈΡΡ
Rust <1.3 ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ .connect();
let number_vector = vec!(1,12,3,1,5);
number_vector.sort(); // 1,1,3,5,12
Π‘ΠΌΠ΅Π½Π° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΏΡΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠΈ:
number_vector.sort_by(|a,b| b.cmp(a));
Π‘ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ°, ΠΏΠΎΡΠΎΠΌ ΡΠ΅Π²Π΅ΡΡ:
number_vector.sort();
number_vector.reverse();
ΠΠ±ΡΡΡΠΊΠ° Reverse Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠΌ Ord:
use std::cmp::Reverse;
number_vector.sort_by_key(|w| Reverse(*w));
ΠΡΠ»ΠΈ Π²Π΅ΡΠ½ΡΡΡ Reverse ΡΠΎ ΡΡΡΠ»ΠΊΠΎΠΉ ΠΈ Π±Π΅Π· *
, ΡΡΠΎ ΠΏΡΠΈΠ²Π΅Π΄ΡΡ ΠΊ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ΅ Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ.
let collected_iterator: Vec<i32> = (0..10).collect();
println!("Collected (0..10) into: {:?}", collected_iterator);
// Collected (0..10) into: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ΠΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ ΠΈΠ· ΠΌΠ°ΡΡΠΈΠ²Π° array Π² vector:
let number_list = [1,12,3,1,5,2];
let number_vector = number_list.to_vec(); // ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ array[i32] -> vector<i32>
ΠΠ°ΡΠΈΠ°Π½Ρ ΡΠ΅ΡΠ΅Π· ΠΈΡΠ΅ΡΠ°ΡΠΎΡ:
let a = [10, 20, 30, 40];
let v: Vec<i32> = a.iter().map(|&e| e as i32).collect();
ΠΠ΅ΠΊΡΠΎΡ ΠΈΠ· Π±Π°ΠΉΡΠΎΠ² vector of bytes Π² ΡΡΡΠΎΠΊΡ String:
use std::str;
fn main() {
let buf = &[0x41u8, 0x41u8, 0x42u8]; // vector of bytes
let s = match str::from_utf8(buf) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
println!("result: {}", s);
}