Sözcük dışı yaşamlar nelerdir?


Yanıtlar:


139

Non-sözcüksel ömürleri ne anlama tarafından ne olduğunu anlamak için en kolay sözcük yaşamları bulunmaktadır. Sözcük dışı yaşam sürelerinden önceki Rust sürümlerinde bu kod başarısız olur:

fn main() {
    let mut scores = vec![1, 2, 3];
    let score = &scores[0];
    scores.push(4);
}

Rust derleyicisi scoresbunun scoredeğişken tarafından ödünç alındığını görür , bu nedenle aşağıdakilerin daha fazla mutasyonuna izin vermez scores:

error[E0502]: cannot borrow `scores` as mutable because it is also borrowed as immutable
 --> src/main.rs:4:5
  |
3 |     let score = &scores[0];
  |                  ------ immutable borrow occurs here
4 |     scores.push(4);
  |     ^^^^^^ mutable borrow occurs here
5 | }
  | - immutable borrow ends here

Ancak, insan trivially bu örnek aşırı muhafazakar olduğunu görebilirsiniz: scoreedilir hiç kullanılmamış ! Problem ocağı olmasıdır scoresgöre scoreolan sözcük - bu yer aldığı bloğun sonuna kadar sürer:

fn main() {
    let mut scores = vec![1, 2, 3]; //
    let score = &scores[0];         //
    scores.push(4);                 //
                                    // <-- score stops borrowing here
}

Sözcüksel olmayan yaşam süreleri, derleyicinin bu ayrıntı düzeyini anlamasını sağlayarak bunu düzeltir. Derleyici artık bir ödünç almanın ne zaman gerekli olduğunu daha doğru bir şekilde söyleyebilir ve bu kod derlenecektir.

Sözcük dışı yaşamlarla ilgili harika bir şey, bir kez etkinleştirildiğinde, hiç kimsenin onlar hakkında düşünmeyeceğidir . Bu basitçe "Rust'un yaptığı" olacak ve işler (umarız) sadece işe yarayacak.

Sözcüksel yaşamlara neden izin verildi?

Rust, yalnızca bilinen güvenli programların derlenmesine izin vermek için tasarlanmıştır. Ancak, yalnızca güvenli programlara tam olarak izin vermek ve güvenli olmayanları reddetmek imkansızdır . Bu amaçla Rust, muhafazakar olma konusunda hata yapıyor: bazı güvenli programlar reddediliyor. Sözcüksel yaşamlar bunun bir örneğidir.

Sözcüksel yaşam sürelerinin derleyicide uygulanması çok daha kolaydı, çünkü blok bilgisi "önemsiz", veri akışı bilgisi ise daha az. Derleyicinin "orta düzey orta düzey gösterimi" (MIR) tanıtmak ve kullanmak için yeniden yazılması gerekiyordu . Daha sonra ödünç alma denetleyicisi ("ödünç" olarak da bilinir) soyut sözdizimi ağacı (AST) yerine MIR kullanmak için yeniden yazılmalıdır. Daha sonra, ödünç alma denetçisinin kurallarının daha ince taneli olması için düzeltilmesi gerekiyordu.

Sözcüksel yaşamlar her zaman programcının önüne geçmez ve sinir bozucu olsalar bile, sözlü yaşamlar etrafında çalışmanın birçok yolu vardır. Çoğu durumda, bu, fazladan küme parantezleri veya bir boole değeri eklemeyi içerir. Bu, Rust 1.0'ın leksik olmayan yaşam süreleri uygulanmadan önce uzun yıllar boyunca gönderilmesine ve yararlı olmasına izin verdi.

İlginç bir şekilde, sözcüksel yaşamlar nedeniyle bazı iyi kalıplar geliştirildi. Benim için enentry önemli örnek modeldir . Bu kod, sözcüksel olmayan yaşam sürelerinden önce başarısız olur ve onunla derlenir:

fn example(mut map: HashMap<i32, i32>, key: i32) {
    match map.get_mut(&key) {
        Some(value) => *value += 1,
        None => {
            map.insert(key, 1);
        }
    }
}

Ancak bu kod, anahtarın karmasını iki kez hesapladığı için verimsizdir. Sözcük yaşam süreleri nedeniyle oluşturulan çözüm daha kısa ve daha etkilidir:

fn example(mut map: HashMap<i32, i32>, key: i32) {
    *map.entry(key).or_insert(0) += 1;
}

"Sözcük dışı yaşamlar" adı bana doğru gelmiyor

Bir değerin yaşam süresi, değerin belirli bir bellek adresinde kaldığı zaman aralığıdır ( daha uzun bir açıklama için neden bir değeri ve bu değere başvuruyu aynı yapıda saklayamıyorum? Bölümüne bakın). Sözcük dışı yaşamlar olarak bilinen özellik , herhangi bir değerin yaşam süresini değiştirmez , bu nedenle yaşamları sözcüksel olmayan hale getiremez. Yalnızca bu değerlerin ödünç alanlarının izlenmesini ve kontrol edilmesini daha hassas hale getirir.

Özellik için daha doğru bir ad, "sözcüksel olmayan ödünç alanlar " olabilir. Bazı derleyici geliştiricileri, temelde yatan "MIR tabanlı ödünç verme" ye başvurur.

Sözcük dışı yaşamlar asla kendi başına "kullanıcıya dönük" bir özellik olarak tasarlanmadı . Yokluklarından aldığımız küçük kağıt kesiği yüzünden çoğunlukla zihnimizde büyüdüler. İsimleri çoğunlukla dahili geliştirme amaçlıydı ve pazarlama amacıyla değiştirmek asla bir öncelik değildi.

Evet ama nasıl kullanırım?

Rust 1.31'de (2018-12-06'da piyasaya sürüldü), Cargo.toml'nizde Rust 2018 sürümüne kaydolmanız gerekir:

[package]
name = "foo"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"

Rust 1.36'dan itibaren, Rust 2015 sürümü sözcüksel olmayan yaşam sürelerine de olanak tanır.

Sözcük dışı yaşam sürelerinin şu anki uygulaması bir "göç kipi" içindedir. NLL ödünç alma denetleyicisi geçerse, derleme devam eder. Aksi takdirde, önceki ödünç alma denetleyicisi çağrılır. Eski ödünç alma denetleyicisi koda izin verirse, size kodunuzun Rust'un gelecekteki bir sürümünde kırılma olasılığının yüksek olduğunu ve güncellenmesi gerektiğini bildiren bir uyarı yazdırılır.

Rust'un gecelik sürümlerinde, bir özellik bayrağı aracılığıyla zorunlu kırılmayı etkinleştirebilirsiniz:

#![feature(nll)]

Derleyici bayrağını kullanarak NLL'nin deneysel sürümüne bile katılabilirsiniz -Z polonius.

Sözcüksel olmayan yaşam süreleri tarafından çözülen gerçek sorunların bir örneği


12
Sanırım, belki de sezginin tersine, Sözcüksel Olmayan Yaşamların değişkenlerin Ömrü hakkında değil, Ödünç Alanların Ömrü ile ilgili olduğunu vurgulamaya değer. Ya da başka türlü söylenirse, Sözcüksel Olmayan Yaşamlar değişkenlerin yaşam sürelerini ödünç alanlarınkinden ayırmakla ilgilidir ... yanılıyorsam? (ama bir yıkıcı yürütüldüğünde NLL'nin değişeceğini düşünmüyorum)
Matthieu M.

2
" İlginç bir şekilde, sözcüksel yaşamlar nedeniyle belirli iyi kalıplar geliştirildi " - Öyleyse, NLL'nin varlığının gelecekte iyi kalıpları tanımlamayı çok daha zor hale getirme riski var mı?
eggyal

1
@eggyal kesinlikle bir olasılık. Bir dizi kısıtlama dahilinde tasarım yapmak (keyfi olsa bile!) Yeni, ilginç tasarımlara yol açabilir. Bu kısıtlamalar olmadan, mevcut bilgi ve kalıplarımıza geri dönebilir ve asla yeni bir şey bulmayı öğrenemez veya keşfetmeyebiliriz. Bununla birlikte, muhtemelen birisi "ah, karma iki kez hesaplanıyor, bunu düzeltebilirim" diye düşünür ve API oluşturulur, ancak kullanıcıların en başta API'yi bulması daha zor olabilir. Umarım clippy gibi araçlar bu insanlara yardımcı olur.
Shepmaster
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.