A Rustban, ha egy értéket egy névhez rendelünk, azt kötésnek nevezzük. A kötések megváltoztathatatlanok, hacsak nem a mut kulcsszóval hozzuk létre őket. Mivel a Rust statikusan típusos nyelv, minden kötés típusa fordítási időben ismert.
A kötéseket leggyakrabban a let kulcsszóval definiáljuk. A kötés típusának megadása a legtöbb kötésnél elhagyható, mert a Rust típuskövetkeztetése általában az értékük alapján ki tudja találni a típust. Egy kötés így néz ki:
// Automatically inferred type
let fingers = 10;
A függvények elemek. Míg a kötések általában egy konkrét értékre hivatkoznak, addig az elemek egy kódszervezési egységre, jellemzően egy függvényre vagy egy modulra, amely a program teljes élettartama alatt elérhető. Egy függvény automatikusan visszaadja az utolsó kifejezésének eredményét. Egy függvénynek 0 vagy több paramétere lehet, amelyek élettartama a függvényhívás idejére korlátozódik.
A típuskövetkeztetés elméletileg a függvényeknél is lehetséges, de szándékos nyelvi tervezési döntés miatt le van tiltva. Ez azt jelenti, hogy kicsit több időt kell kódírás közben azzal töltened, hogy pontosan megadd egy függvény bemeneti és kimeneti típusát, viszont időt spórolsz a kód olvasásakor, mivel minden bemeneti és kimeneti típus explicit módon definiálva van.
fn add(x: i32, y: i32) -> i32 {
x + y
}
Egy függvényt úgy hívunk meg, hogy megadjuk a nevét, majd zárójeleket írunk utána. Ha a függvény paramétereket vár, mindegyikhez meg kell adni egy argumentumot a zárójeleken belül.
let five = add(2, 3);
Ha egy kötés típusát nem lehet kikövetkeztetni, a fordító hibát jelez. Ennek kijavításához adj hozzá egy explicit típusannotációt a kötéshez.
// Explicit type annotation
let fingers: i32 = 10;
A Rust elemei a definiálásuk előtt és után is használhatók, mert statikus élettartammal rendelkeznek. A kötések viszont csak azután használhatók, hogy definiáltuk őket. Ha egy kötést a definiálása előtt használunk, az fordítási hibát eredményez.
fn main() {
// `fn add` hasn't yet been defined, but that's perfectly ok
dbg!(add(3, 4));
}
fn add(x: i32, y: i32) -> i32 {
x + y
}
// this won't compile; `a` is used before its binding is defined
let b = a;
let a = x + y;
A Rust kapcsos zárójelekkel ({}) definiál egy scope-ot. Egy scope-ban definiált kötés nem tud kikerülni belőle.
let a = 1;
dbg!(a); // 1
{
// Here, we re-bind `a` to a new value, which is still immutable.
// This technique is called _shadowing_. The new binding is constrained to
// this anonymous scope. Outside this scope, the previous binding still
// applies.
let a = 2;
let b = 3;
dbg!(a, b); // 2, 3
}
// can't use `b` anymore because it is out of scope
// dbg!(b);
// The shadowed `a` in the inner scope above has fallen out of scope,
// leaving us with our original binding.
dbg!(a); // 1
A Rust elemeit gyakran modulokba szervezzük. Minden crate implicit módon egy modul, de tetszőleges mélységű belső almodulokat is definiálhat. Egy modul összetartozó funkcionalitást csoportosít, és a mod kulcsszóval definiáljuk.
mod calc_i32 {
fn add(a: i32, b: i32) -> i32 { a + b }
fn sub(a: i32, b: i32) -> i32 { a - b }
fn mul(a: i32, b: i32) -> i32 { a * b }
fn div(a: i32, b: i32) -> i32 { a / b }
}
A Rust kétféle megjegyzést támogat. A // kulcsszó egysoros megjegyzést jelöl; a kulcsszó után minden figyelmen kívül marad a sor végéig. A /* és */ kulcsszavak többsoros megjegyzést jelölnek; minden figyelmen kívül marad, ami e két kulcsszó között van. Az egysoros megjegyzések előnyben részesítése idiomatikus és jó gyakorlat.
A Rust emellett dokumentációs megjegyzéseket is támogat, amelyek megjelennek a cargo doc által generált dokumentációban. A külső dokumentációs megjegyzéseket a /// kulcsszóval készítjük, amely pontosan úgy működik, mint a // kulcsszó. Arra az elemre vonatkoznak, amely után állnak, például egy függvényre:
/// The `add` function produces the sum of its arguments.
fn add(x: i32, y: i32) -> i32 { x + y }
A belső dokumentációs megjegyzéseket a //! kulcsszóval készítjük, amely pontosan úgy működik, mint a // kulcsszó. Arra az elemre vonatkoznak, amely körülveszi őket, például egy modulra:
mod my_cool_module {
//! This module is the bee's knees.
}
A dokumentációs megjegyzések tetszőleges hosszúságúak lehetnek, és markdown tartalmat tartalmazhatnak, amely bekerül a generált dokumentációba.
Ebben a feladatban olyan kódot írsz, amely segít elkészíteni egy pompás lasagnát a kedvenc szakácskönyvedből.
Négy részfeladatot kell megoldanod, amelyek mind a lasagna elkészítésével töltött időhöz kapcsolódnak.
Definiáld az expected_minutes_in_oven kötést, amellyel ellenőrizheted, hány percig kell a lasagnának a sütőben lennie. A szakácskönyv szerint a várható sütési idő 40 perc:
expected_minutes_in_oven()
// Returns: 40
Definiáld a remaining_minutes_in_oven függvényt, amely paraméterként a lasagnának a sütőben töltött tényleges perceit kapja meg, és visszaadja, hogy a lasagnának az előző részfeladatban megadott várható sütési idő alapján hány percig kell még a sütőben maradnia.
remaining_minutes_in_oven(30)
// Returns: 10
Definiáld a preparation_time_in_minutes függvényt, amely paraméterként a lasagnához adott rétegek számát kapja meg, és visszaadja, hogy hány percet töltöttél a lasagna előkészítésével, feltéve, hogy egy réteg elkészítése 2 percet vesz igénybe.
preparation_time_in_minutes(2)
// Returns: 4
Definiáld az elapsed_time_in_minutes függvényt, amely két paramétert kap: az első paraméter a lasagnához adott rétegek száma, a második paraméter pedig az, hogy a lasagna hány perce van a sütőben. A függvény adja vissza, hogy hány percet dolgoztál a lasagna elkészítésén, ami a percekben mért előkészítési idő és a lasagnának a sütőben eddig eltöltött idejének összege.
elapsed_time_in_minutes(3, 20)
// Returns: 26
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Rust nyelvet 99 feladat segítségével, valódi emberi mentorálással, mindez ingyen.