Məzmuna keç
Educora
Başlanğıc15 dəq3 / 10

Funksiyalar, ifadələr və idarəetmə axını

Funksiyalar yaz, ifadə ilə təlimatın fərqini anla, `if`-i qiymət qaytaran ifadə kimi işlət və `loop`, `while`, `for` dövrlərini diapazonlarla birlikdə tətbiq et.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Parametrli və qiymət qaytaran funksiyalar yazmaq
  • İfadə ilə təlimatı ayırmaq və nöqtəli vergülün rolunu izah etmək
  • if-dən ifadə kimi istifadə etmək
  • loop, while və for dövrlərini diapazonlarla yazmaq

Çay dəmləmə resepti «suyu qaynat», «çayniki isit», «çayı dəmə qoy» kimi adlı addımlardan ibarətdir. Bəzi addımlar şərtdən asılıdır («su qaynayıbsa…»), bəziləri isə təkrarlanır («hər stəkana tök»). Proqramlar da belə qurulur: adlı addımlar funksiyalar, qərarlar **if, təkrarlar isə dövrlər** ilə yazılır.

Funksiyalar

Funksiya fn açar sözü ilə elan olunur, adı snake_case üslubunda yazılır. Hər parametrin tipi mütləq göstərilməlidir. Funksiya qiymət qaytarırsa, onun tipi -> oxundan sonra yazılır. Funksiyaların faylda hansı sırada yazılması fərq etmir: main özündən aşağıda elan olunan funksiyanı da çağıra bilər.

Rust
fn main() {
    greet("Leyla");
    let a = area(3, 4);
    println!("Area: {a}");
}

fn greet(name: &str) {
    println!("Hello, {name}!");
}

fn area(width: u32, height: u32) -> u32 {
    width * height
}
Gözlənilən nəticə
Hello, Leyla!
Area: 12
&str mətn tipidir (onu 4-cü dərsdə ətraflı öyrənəcəyik). area funksiyasında return yoxdur: sonuncu ifadə olan width * height avtomatik qaytarılır.

İfadələr və təlimatlar

Tərif
İfadə və təlimat

İfadə (expression) hesablanıb qiymət verən koddur: 5 + 3, area(2, 3), { } bloku, if. Təlimat (statement) isə bir iş görür, amma qiymət vermir: let x = 5; və ya sonunda ; olan istənilən sətir. İfadənin sonuna ; qoymaq onu təlimata çevirir.

Rust
fn main() {
    let y = {
        let x = 3;
        x * x + 1
    };
    println!("y = {y}");
}
Gözlənilən nəticə
y = 10
Blokun qiyməti onun sonuncu ifadəsidir: x * x + 1 sətrinin sonunda ; yoxdur.
Xəta E0308
fn square(x: i32) -> i32 {
    x * x;
}
Düzgün
fn square(x: i32) -> i32 {
    x * x
}
Solda ; ifadəni təlimata çevirdi, funksiya isə heç nə — boş () tipini qaytarır. Kompilyator i32 gözləyirdi və nöqtəli vergülü silməyi məsləhət görür.
Text
error[E0308]: mismatched types
 --> src/main.rs:1:22
  |
1 | fn square(x: i32) -> i32 {
  |    ------            ^^^ expected `i32`, found `()`
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression
2 |     x * x;
  |          - help: remove this semicolon to return this value

if — qiymət qaytaran şərt

Rust-da if şərtinin mötərizəyə ehtiyacı yoxdur, fiqurlu mötərizələr isə mütləqdir. Şərt mütləq bool tipində olmalıdır. if həm də ifadədir: onun nəticəsini dəyişənə yazmaq və ya funksiyadan qaytarmaq olar. Bunun üçün bütün qolların qiymətləri eyni tipdə olmalıdır.

Rust
fn grade(score: u32) -> char {
    if score >= 90 {
        'A'
    } else if score >= 70 {
        'B'
    } else {
        'C'
    }
}

fn main() {
    let temperature = 28;
    let clothes = if temperature > 25 { "T-shirt" } else { "jacket" };
    println!("Wear a {clothes}");
    println!("95 -> {}", grade(95));
    println!("72 -> {}", grade(72));
    println!("40 -> {}", grade(40));
}
Gözlənilən nəticə
Wear a T-shirt
95 -> A
72 -> B
40 -> C

Dövrlər: loop, while, for

Rust-da üç dövr var. loop break ilə dayandırılana qədər sonsuz təkrarlanır və break ilə qiymət də qaytara bilər. while şərt doğru olduqca işləyir. for isə kolleksiyanın və ya diapazonun elementlərini bir-bir gəzir — bu, ən çox istifadə olunan və ən təhlükəsiz dövrdür.

Rust
fn main() {
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 5 {
            break counter * 10;
        }
    };
    println!("result = {result}");

    let mut n = 3;
    while n > 0 {
        println!("{n}...");
        n -= 1;
    }
    println!("Liftoff!");
}
Gözlənilən nəticə
result = 50
3...
2...
1...
Liftoff!
Rust
fn main() {
    for i in 1..4 {
        print!("{i} ");
    }
    println!();

    for i in (1..=3).rev() {
        print!("{i} ");
    }
    println!();

    let cities = ["Baku", "Ganja", "Shaki"];
    for (index, city) in cities.iter().enumerate() {
        println!("{index}: {city}");
    }

    let total: i32 = (1..=100).sum();
    println!("1 + 2 + ... + 100 = {total}");
}
Gözlənilən nəticə
1 2 3 
3 2 1 
0: Baku
1: Ganja
2: Shaki
1 + 2 + ... + 100 = 5050
print! yeni sətrə keçmədən çap edir, boş println!() isə yeni sətrə keçir. enumerate() hər elementə onun indeksini əlavə edir.
YazılışQiymətlərQeyd
1..41, 2, 3son daxil deyil
1..=41, 2, 3, 4son daxildir
(1..4).rev()3, 2, 1tərsinə
(0..10).step_by(3)0, 3, 6, 9addımla

İç-içə dövrlərdə break yalnız ən daxili dövrü dayandırır. Xarici dövrü dayandırmaq üçün ona apostrofla başlayan nişan (label) ver və break 'nişan yaz:

Rust
fn main() {
    'outer: for row in 1..=3 {
        for col in 1..=3 {
            if row * col == 4 {
                println!("found at ({row}, {col})");
                break 'outer;
            }
        }
    }
    println!("search finished");
}
Gözlənilən nəticə
found at (2, 2)
search finished

Əsas fikirlər

  • Funksiya fn ilə elan olunur; parametrlərin tipi mütləqdir, qaytarılan tip -> ilə göstərilir.
  • İfadə qiymət verir, təlimat vermir; sonundakı ; ifadəni təlimata çevirir.
  • Funksiyanın və ya blokun sonuncu ;-siz ifadəsi onun qiymətidir.
  • if ifadədir, şərt isə mütləq bool olmalıdır.
  • loop break ilə qiymət qaytara bilər; for diapazonlarla işləyir: 1..4 sonu daxil etmir, 1..=4 edir.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Hansı funksiya ədədin kvadratını düzgün qaytarır?