unsafe fn
- Rust kursu
- İleri seviye
- Ders 32/81
- 4 dk
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
fn main() {
// buraya yaz
}Örnek çözüm
/// İş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
t += unsafe { *v.____(i) };
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 |