[[oktatas:programozás:rust|< Rust]]
====== Rust nyelv ======
* **Szerző:** Sallai András
* Copyright (c) Sallai András, 2020
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]]
* Web: https://szit.hu
===== Helló Világ =====
fn main() {
println!("Helló Világ!");
}
Fordítás:
rustc hello.rs
Futtatás:
./hello
A ! azt jelenti, hogy a println nem függvény, hanem makró.
A makrók újabb kódokat hoznak létre, fordításkor.
===== Megjegyzések =====
// egy soros megjegyzés
/*
több
soros
megjegyzés
*/
===== Kivitel =====
Kiíratás sortörés nélkül:
print!("alma");
A rust nyelven nem íratható ki önmagában egy szám literálist.
println!(35)
Csak így:
println!("{}", 35);
Tájékoztató szöveget is megadhatunk a kiírt értékről:
println!("Szám: {}", 35);
Több literális kiíratása:
println!("{1} és {0}", 25, 47);
Kifejezés kiértékelése:
fn main() {
println!("{}", 3*4)
}
Új sor kiíratása:
println!();
Hibaüzenet kiírása:
eprintln!("Hiba! ...");
Hibaüzenet sortörés nélkül:
eprint!("Hiba! ...");
===== Primitív típusok =====
Egészek:
^ Hossz ^ Előjeles ^ Előjel \\ nélkül |
| 8 bites | i8 | u8 |
| 16 bites | i16 | u16 |
| 32 bites | i32 | u32 |
| 64 bites | i64 | u64 |
| 128 bites | i128 | u128 |
Egész literális:
| decimális | 23_123 |
| hexadecimális | 0xfe |
| oktális | 0o75 |
| bináris | 0b1111_0000 |
| bájt (csak u8) | b'A' |
Valós számok:
* f32
* f64
let szam1 = 3.0; //f64
let szam2: f32 = 3.0 // f32
Logikai típus:
* bool
let van = true;
let nincs = true;
Karakter:
* char
let c = 'a';
Összetett típusok:
* Tuple
* Array
Tuple:
let tup: (f32, u8, i32) = (5.48, 3, 600)
Tömb:
let tomb: [5, 8, 2, 4, 1];
A Rust statikusan tipizált nyelv, ami azt jelenti, hogy
fordítási időben ismernie kell a változók típusát,
azonban a fordító általában érték és a használat
alapján dönti el, milyen típust akarunk használni.
Készítsünk egy "a" nevű változót:
let a = 35;
Az "a" változó értéke alapértelmezetten i32.
Valós szám esetén:
let a = 35.5;
Alapértelmezett f64.
A típus explicit megadása:
let a: i64 = 834983434;
A maximálisan tárolható legnagyobb szám kiíratása:
println!("Max i32: {}", std::i32::MAX);
Logikai típus megadása:
let aktiv: bool = true;
A logika típus kifejezéssel is kaphat értéket:
let nagyobb: bool = a > 30;
Karakterek:
let karakter1 = 'a'
let karakter2 = '\u{7a7a}';
===== Változóhasználat =====
A változók tartalmazhatnak primitív és referencia típusokat.
A változók alapértelmezetten nem megváltoztathatók (immutable).
fn main() {
let kor = 35;
println!("{}", kor);
}
Mivel alapértelmezetten nem változtatható meg egy változó értéke,
ha beírjuk kor = 36, akkor hibát ad a fordító:
fn main() {
let kor = 35;
//A következő utasítás hibát ad:
//kor = 36;
println!("{}", kor);
}
Megváltoztathatóvá tehetjük a mut kulcsszóval:
fn main() {
let mut kor = 35;
println!("{}", kor);
kor = 36;
println!("{}", kor);
}
Viszont hibát kapunk, ha az első println!() utasítás hiányzik, mivel
fel sem használtuk a kor változó értékét, és máris megváltoztatjuk.
Többes értékadás:
let (nev, kor) = ("Nagy János", 38);
println!("Név: {}", nev);
println!("Kor: {}", kor);
===== Nevesített állandók =====
Állandók a const kulcsszóval hozhatók létre, és kötelezően nagybetűsek.
const ID: i32 = 001;
println!("azonosító: {}", ID);
===== Formázott kivitel =====
Szöveg kiírása:
fn main() {
println!("{} származik {}", "Szolnokról", "Laci")
}
Pozicionális argumentum:
fn main() {
println!("{0} {1}ról származik és {0} szereti {2}t",
"Laci", "Szolnok", "Mari")
}
Elnevezett argumentumok:
fn main() {
println!(
"{nev} szeret {jatek}t játszani",
nev = "Laci",
jatek = "Póker"
);
}
Írassuk ki a 10 számot bináris, hexadecimális és oktális alakban:
println!("bináris: {:b} Hex: {:x} Oktális: {:o}", 10, 10, 10);
Bármit kiírathatunk, például hibakövetés céljából:
println!("{:?}", ("alma", 35, true));
A kiíratás eredménye:
("alma", 35, true)
Másik példa:
fn main() {
let a = true;
let b = 35;
let c = 35.6;
println!("{:?}", (a, b, c))
}
Kimenet:
(true, 35, 35.6)
===== Matematikai modul =====
===== Véletlen szám =====
===== Operátorok =====
===== Konvertálás =====
===== Bevitel =====
===== Szelekció =====
fn main() {
let kor = 35;
if kor > 21 {
println!("Felnőtt");
}
}
fn main() {
let kor = 35;
if kor > 21 {
println!("Felnőtt");
} else {
println!("Gyerek")
}
}
Logikai típus használata:
fn main() {
let felnott: bool = true;
if felnott {
println!("Felnőtt");
} else {
println!("Gyerek")
}
}
Két állítás:
fn main() {
let van_diplomaja: bool = true;
let van_jogositvanya: bool = true;
if van_diplomaja && van_jogositvanya {
println!("Felvéve");
} else {
println!("Sajnos, nem nyert")
}
}
Két állítás vagy kapcsolattal:
fn main() {
let van_haza = true;
let van_kocsija = false;
if van_haza || van_kocsija {
println!("Nyerő");
} else {
println!("Nem nyerő");
}
}
Több elágazás:
fn main() {
let kor = 25;
if kor < 1 {
println!("Csecsemő");
} else if kor > 1 && kor <= 6 {
println!("Kisgyermek");
} else if kor > 6 && kor <= 12 {
println!("Gyermek");
} else if kor > 12 && kor <= 16 {
println!("Serdülő");
} else if kor > 16 && kor <= 20 {
println!("Ifjú");
} else if kor > 20 && kor <= 30 {
println!("Fiatal");
} else {
println!("Öregedés...");
}
}
==== Rövidített if ====
fn main() {
let fizetes = 2800000;
let megfelel = if fizetes > 1000000 { true } else { false };
println!("{}", megfelel);
}
===== Iteráció =====
==== Loop ====
fn main() {
let mut szamlalo = 0;
loop {
println!("{}", szamlalo);
szamlalo += 1;
if szamlalo == 10 {
break;
}
}
}
==== While ====
fn main() {
let mut szamlalo = 0;
while szamlalo < 10 {
println!("{}", szamlalo);
szamlalo += 1;
}
}
==== for range ====
fn main() {
for i in 0..9 {
println!("{}", i)
}
}
===== Tömb =====
A tömb azonos típusú értékeket tartalmazó adatszerkezet.
fn main() {
let szamok: [i32; 6] = [ 3, 4, 2, 8, 1, 5];
println!("{:?}", szamok);
println!("Első érték: {}", szamok[0]);
}
Egy elem új értékadásához szükség van a "mut" módosítóra.
fn main() {
let mut szamok: [i32; 6] = [ 3, 4, 2, 8, 1, 5];
szamok[0] = 25;
println!("{:?}", szamok);
}
Hossz:
println!("{:?}", szamok.len());
A veremben elfoglalt hely:
println!("{:?}", std::mem::size_of_val(&szamok));
==== Darab ====
fn main() {
let szamok: [i32; 6] = [ 3, 4, 2, 8, 1, 5];
let darab: &[i32] = &szamok[0..3];
println!("{:?}", darab);
}
==== Tömb másik tömbből ====
fn main() {
let tomb1 = [8, 2, 5];
let tomb2 = tomb1;
println!("{:?}", (tomb1, tomb2));
}
===== Tuple =====
fn main() {
let dolgozo: (&str, &str, i32) = ("Nagy János", "Miskolc", 3280000);
println!("Név: {}\nTelepülés: {}\nFizetés: {}",
dolgozo.0, dolgozo.1, dolgozo.2);
}
===== Vektor =====
fn main() {
let mut szamok: Vec = vec![ 3, 4, 2, 8, 1, 5];
//Összes elem kiírása
println!("{:?}", szamok);
//Egy elemre hivatkozás
println!("{}", szamok[0]);
//Hozzáadunk egy elemet:
szamok.push(37);
szamok.push(25);
println!("{:?}", szamok);
szamok.pop();
println!("{:?}", szamok);
}
Vektor bejárása:
fn main() {
let szamok: Vec = vec![ 3, 4, 2, 8, 1, 5];
for elem in szamok.iter() {
println!("{}", elem);
}
}
Bejárás és értékek változtatása:
fn main() {
let mut szamok: Vec = vec![ 3, 4, 2, 8, 1, 5];
for elem in szamok.iter_mut() {
*elem += 4;
}
println!("{:?}", szamok)
}
Hivatkozás átadása:
fn main() {
let vektor1 = vec![8, 3, 7];
let vektor2 = &vektor1;
println!("{:?}", (&vektor1, vektor2));
}
===== Struktúra =====
struct Dolgozo<'a> {
//Az 'a egy lifetime
nev: &'a str,
kor: u8,
fizetes: f64,
}
fn main() {
let janos = Dolgozo {
nev: "Nagy János",
kor: 35,
fizetes: 3850000.0,
};
println!("Név: {}\nKor: {}\nFizetés: {}",
janos.nev, janos.kor, janos.fizetes);
}
Mutable:
struct Dolgozo<'a> {
//Az 'a egy lifetime
nev: &'a str,
kor: u8,
fizetes: f64,
}
fn main() {
let mut janos = Dolgozo {
nev: "Nagy János",
kor: 35,
fizetes: 3850000.0,
};
janos.kor = 36;
println!("Név: {}\nKor: {}\nFizetés: {}",
janos.nev, janos.kor, janos.fizetes);
}
==== Tuple struktúra ====
struct Dolgozo<'a>(&'a str, u8, f64);
fn main() {
let mut janos = Dolgozo("Nagy János", 36, 3850000.0);
janos.1 = 37;
println!("Név: {}\nKor: {}\nFizetés: {}", janos.0, janos.1, janos.2);
}
==== A sturktúra ====
struct Dolgozo {
nev: String,
telepules: String
}
impl Dolgozo {
fn new(atvett_nev: &str, atvett_telepules: &str) -> Dolgozo {
Dolgozo {
nev: atvett_nev.to_string(),
telepules: atvett_telepules.to_string()
}
}
}
fn main() {
let janos = Dolgozo::new("Nagy János", "Szolnok");
println!("Név: {}\nTelepülés: {}", janos.nev, janos.telepules);
}
Beállítható név:
struct Dolgozo {
nev: String,
telepules: String
}
impl Dolgozo {
fn new(atvett_nev: &str, atvett_telepules: &str) -> Dolgozo {
Dolgozo {
nev: atvett_nev.to_string(),
telepules: atvett_telepules.to_string()
}
}
fn set_nev(&mut self, atvett_nev: &str) {
self.nev = atvett_nev.to_string();
}
}
fn main() {
let mut janos = Dolgozo::new("Nagy János", "Szolnok");
janos.set_nev("Kiss Béla");
println!("Név: {}\nTelepülés: {}", janos.nev, janos.telepules);
}
Átalakítás tuple formára:
struct Dolgozo {
nev: String,
telepules: String
}
impl Dolgozo {
fn new(atvett_nev: &str, atvett_telepules: &str) -> Dolgozo {
Dolgozo {
nev: atvett_nev.to_string(),
telepules: atvett_telepules.to_string()
}
}
fn set_nev(&mut self, atvett_nev: &str) {
self.nev = atvett_nev.to_string();
}
fn to_tuple(self) -> (String, String) {
(self.nev, self.telepules)
}
}
fn main() {
let mut janos = Dolgozo::new("Nagy János", "Szolnok");
janos.set_nev("Kiss Béla");
println!("Név: {}\nTelepülés: {}", janos.nev, janos.telepules);
println!("{:?}", janos.to_tuple());
}
===== Enum =====
enum Mozgas {
Fel,
Le,
Balra,
Jobbra
}
fn avatar_mozgatas(m: Mozgas) {
match m {
Mozgas::Fel => println!("Mozgás fel"),
Mozgas::Le => println!("Mozgás le"),
Mozgas::Balra => println!("Mozgás balra"),
Mozgas::Jobbra => println!("Mozgás jobbra"),
}
}
fn main() {
let avatar1 = Mozgas::Balra;
let avatar2 = Mozgas::Jobbra;
let avatar3 = Mozgas::Fel;
let avatar4 = Mozgas::Le;
avatar_mozgatas(avatar1);
avatar_mozgatas(avatar2);
avatar_mozgatas(avatar3);
avatar_mozgatas(avatar4);
}
===== String kezelés =====
Primitív str egy fix hosszúságú string valahol a memóriában,
ami nem változtatható (immutable).
fn main() {
let nev = "Nagy János";
println!("{}", nev);
}
A String növelhető, halomterületen (heap-ben) tárolt adatstruktúra.
fn main() {
let nev = String::from("Nagy János");
println!("{}", nev);
}
==== Hossz ====
fn main() {
let nev = String::from("Nagy János");
let hossz = nev.len();
println!("{}", hossz);
}
==== Hozzáfűzés ====
A szoveg változó elé tesszük a mut módosítót, majd hozzáfűzünk egy karaktersorozatot,
és egy betűt.
fn main() {
let mut szoveg = String::from("Nagy János");
szoveg.push_str(" neve");
szoveg.push('t');
println!("{}", szoveg);
}
==== Kapacitás bájtban ====
fn main() {
let szoveg = String::from("Nagy János");
println!("{}", szoveg.capacity());
}
==== Üres ====
println!("{}", szoveg.is_empty());
==== Tartalmazás ====
fn main() {
let szoveg = String::from("Nagy János");
println!("{}", szoveg.contains("János"));
}
Az eredmény egy logikai típus.
==== Csere ====
fn main() {
let szoveg = String::from("Nagy János");
println!("{}", szoveg.replace("Nagy", "Kiss"));
}
==== Darabolás ====
Darabolás whitespace karakterek mentén:
fn main() {
let szoveg = String::from("Nagy János");
for szo in szoveg.split_whitespace() {
println!("{}", szo);
}
}
==== Létrehozás kapacitással ====
fn main() {
let mut szoveg = String::with_capacity(10);
szoveg.push('a');
szoveg.push('b');
println!("{}", szoveg)
}
==== Assert teszt ====
fn main() {
let mut szoveg = String::with_capacity(10);
szoveg.push('a');
szoveg.push('b');
println!("{}", szoveg);
assert_eq!(2, szoveg.len());
assert_eq!(10, szoveg.capacity());
}
===== Függvény =====
Egyszerű függvény:
fn main() {
nevjegy();
}
fn nevjegy() {
println!("-----------------------");
println!(" Nagy János");
println!(" Szolnok");
println!("-----------------------");
}
Egy paraméter:
fn main() {
println!("{}", dupla(35));
}
fn dupla(szam: i32) -> i32 {
return szam * 2;
}
Két paraméter:
fn main() {
println!("{}", osszead(35, 40));
}
fn osszead(szam1: i32, szam2: i32) -> i32 {
return szam1 + szam2;
}
Szöveges paraméterek:
fn main() {
nevjegy("Nagy János", "Szolnok");
}
fn nevjegy(nev: &str, telepules: &str) {
println!("----------------------");
println!(" {}", nev);
println!(" {}", telepules);
println!("----------------------");
}
Closure:
fn main() {
let osszead = |szam1: i32, szam2: i32| szam1 + szam2;
println!("{}", osszead(25, 30));
}
===== A cargo =====
A rust csomaghoz ajánlott a cargo, ami automatikusan feltelepszik.
Használata:
cargo init
Létrejön egy Cargo fájl:
[package]
name = "hello"
version = "0.1.0"
authors = ["Nagy János "]
edition "2018"
[dependencies]
/target
**/*.rs.bk
fn main() {
println!("Hello, world");
}
Futtatás:
cargo run
Fordítás:
cargo build
Release:
cargo build --release
===== Modul =====
pub fn nevjegy() {
println!("Valaki")
}
mod egyeb;
fn main() {
egyeb::nevjegy();
}
===== CLI =====
Parancssori argumentumok feldolgozása:
use std::env;
fn main() {
let args: Vec = env::args().collect();
println!("{:?}", args);
}
Ha cargo-val futtatjuk:
cargu run valami
Egyik paraméter:
use std::env;
fn main() {
let args: Vec = env::args().collect();
let parameter = args[1].clone();
println!("Paraméter: {}", parameter);
}
Paraméter ellenőrzése:
use std::env;
fn main() {
let args: Vec = env::args().collect();
let parameter = args[1].clone();
if parameter == "valami" {
println!("Igen, valami");
} else if parameter == "mas" {
println!("Más");
} else {
println!("Ismeretlen paraméter!")
}
}
===== Forrás =====
* https://doc.rust-lang.org/book/ (2020)
* https://www.youtube.com/watch?v=zF34dRivLOw (2020)