[[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)