CodeBlanks Logo Icon CodeBlanks

unsafe fn

unsafe fn tanımlamayı ve çağırmayı öğrenirsin.

unsafe fn

unsafe fn, çağıranın uyması gereken ve derleyicinin denetleyemediği bir sözleşmesi olan fonksiyondur. Sözleşme # Safety başlıklı belge yorumunda yazılır; çağıran tarafta unsafe blok gerekir:

/// İşaretçinin gösterdiği değeri okur.
///
/// # Safety
/// `p` geçerli, hizalı ve başlatılmış bir `i32`'ye işaret etmelidir.
unsafe fn oku(p: *const i32) -> i32 {
    unsafe { *p }
}

let x = 7;
let n = unsafe { oku(&x) };

Standart kütüphanede örnekler: get_unchecked, from_utf8_unchecked, slice::from_raw_parts.

Güvenli sarmalayıcı

Unsafe çağrıyı güvenli bir fonksiyonun içine koyup sözleşmeyi orada sağlamak, kullanıcıyı unsafe'ten kurtarır:

fn toplam_hizli(v: &[i32]) -> i32 {
    let mut t = 0;
    for i in 0..v.len() {
        // SAFETY: i < v.len() döngü aralığından gelir.
        t += unsafe { *v.get_unchecked(i) };
    }
    t
}

Fonksiyonun kendisi güvenlidir: hangi dilimle çağrılırsa çağrılsın tanımsız davranış oluşamaz.

Uygulama Güvenli sarmalayıcı

Belgeli bir unsafe fn oku(p: *const i32) -> i32 ve yukarıdaki güvenli toplam_hizli fonksiyonunu yaz. let x = 7; için oku(&x) ve [1, 2, 3, 4] için toplam_hizli sonuçlarını boşlukla yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
/// İşaretçinin gösterdiği değeri okur.
///
/// # Safety
/// `p` geçerli, hizalı ve başlatılmış bir `i32`'ye işaret etmelidir.
unsafe fn oku(p: *const i32) -> i32 {
    unsafe { *p }
}

fn toplam_hizli(v: &[i32]) -> i32 {
    let mut t = 0;
    for i in 0..v.len() {
        // SAFETY: i < v.len() döngü aralığından gelir.
        t += unsafe { *v.get_unchecked(i) };
    }
    t
}

fn main() {
    let x = 7;
    let n = unsafe { oku(&x) };
    println!("{} {}", n, toplam_hizli(&[1, 2, 3, 4]));
}

Beklenen çıktı

7 10

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>get_unchecked(i)</code> ne zaman güvenle kullanılabilir?

  • Yalnızca release'te
  • i'nin sınırlar içinde olduğu başka bir yolla kesin bilindiğinde Doğru cevap
  • Her zaman
  • Hiçbir zaman

Açıklama: Döngü 0..v.len() aralığındaysa sınır zaten kanıtlıdır; yine de derleyici çoğu zaman sınır denetimini kendisi kaldırır, önce ölç.

2 Sınırsız erişim

Soru
t += unsafe { *v.____(i) };
Cevap
t += unsafe { *v.get_unchecked(i) };

Açıklama: get_unchecked sınır denetimi yapmaz; sözleşme çağırandadır.

3 Öğe ve anlamı

Kavram Anlamı
unsafe fn Sözleşmeli fonksiyon
# Safety Sözleşme belgesi
// SAFETY: Sözleşmenin sağlandığı yer
Güvenli sarmalayıcı Unsafe'i gizler

İleri seviye bölümündeki tüm dersler