Rust yapısında değişkenleri başlatmanın daha hızlı / daha kısa bir yolu var mı?


103

Aşağıdaki örnekte, alanların bildiriminde yapıdaki her alana bir değer atamayı tercih ederim. Alternatif olarak, her alan için alanlara bir değer atamak için etkin bir şekilde bir ek ifade alır. Yapmak istediğim tek şey, yapı somutlaştırıldığında varsayılan değerler atamak.

Bunu yapmanın daha kısa ve öz bir yolu var mı?

struct cParams {
    iInsertMax: i64,
    iUpdateMax: i64,
    iDeleteMax: i64,
    iInstanceMax: i64,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

impl cParams {
    fn new() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

Yanıtlar:


162

Özelliği uygulayarak yapınız için varsayılan değerler sağlayabilirsiniz Default. defaultFonksiyon mevcut gibi görünecektir newfonksiyonu:

impl Default for cParams {
    fn default() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

Daha sonra yapıyı yalnızca varsayılan olmayan değerleri vererek başlatabilirsiniz:

let p = cParams { iInsertMax: 10, ..Default::default() };

Veri yapınızdaki bazı küçük değişikliklerle, otomatik olarak türetilmiş bir varsayılan uygulamadan yararlanabilirsiniz. Eğer kullanırsanız #[derive(Default)]veri yapısı üzerinde, derleyici otomatik olarak varsayılan değeri ile her alanı doldurur sizin için bir varsayılan işlevi yaratacaktır. Varsayılan boole değeri false, varsayılan integral değeri 0'dır.

Tamsayı alanlarının varsayılan olarak -1 olmasını istediğiniz için bir tamsayının varsayılan değerinin 0 olması bir sorundur. Varsayılan -1 değerini uygulayan yeni bir tür tanımlayabilir ve i64yapınız yerine bunu kullanabilirsiniz . (Bunu test etmedim ama işe yaramalı).

Ancak, veri yapınızı biraz değiştirmenizi ve Option<i64>bunun yerine kullanmanızı öneririm i64. Kodunuzun bağlamını bilmiyorum, ancak "sonsuz" veya "maksimum yok" özel anlamını temsil etmek için özel -1 değerini kullanıyorsunuz gibi görünüyor. Rust'ta, Optionisteğe bağlı olarak mevcut bir değeri temsil etmek için bir kullanırız. -1 hack'e gerek yoktur. Bir seçenek, ya Noneda Some(x)burada x'in sizin olabileceği yer olabilir i64. Tek negatif değer -1 ise, işaretsiz bir tamsayı bile olabilir. Varsayılan Optiondeğer şudur None, bu nedenle önerilen değişikliklerle kodunuz şöyle görünebilir:

#[derive(Default)]
struct cParams {
    iInsertMax: Option<u64>,
    iUpdateMax: Option<u64>,
    iDeleteMax: Option<u64>,
    iInstanceMax: Option<u64>,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

let p = cParams { iInsertMax: Some(10), ..Default::default() };

2
Teşekkürler, hızlı bir şekilde okudum, ancak daha iyi anlamak için yeniden okuyacağım. Sıfır, yanlış, "" gibi bazı dillerin kullandığı "doğal" varsayılanlar bana uyar. Çözmem gereken küçük "sorunumdan" daha geniş çıkarımlar olduğunu anlıyorum. Örneğin belirtme yeteneği. "iVal: i64 = 0", daha geniş ihtiyaçlarımı çözerdi, ama sanırım bu olmayacak. "# [Türetme (Varsayılan)]", isteklerimin çoğunu çözmelidir. Test programımda neden -1 kullandığımdan emin değilim, ancak buna gerek yok (tarihi). Alanın tanımlandığı yerde yerinde bir değer atayabilmek çok faydalı olacaktır (IMHO).
Brian Oh

9
@BrianOh, teğetsel olarak, "yapı alanları için varsayılan değerler" (yani benzeri bir şey struct Foo { val: i64 = 0 }) önerilmiştir ve bu nedenle sonraki sürümlerde görünebilir.
huon

IMO - "struct foo {...." uygulanmış olsaydı iyi olurdu. Yapıyı sorumda yazılı olarak ve varsayılan olarak kullanarak, sizin tarafınızdan önerilen değişiklikleri yaptım. Bu kesinlikle bana daha çok uyuyor ve çok daha özlü. Sözdizimine aşina olmadığım için, karşılaştığım küçük bir sorun TÜM varsayılanlar için sözdizimini bilmemekti. IE: "= cParams {iInsertMax: 10, ..Default :: default ()};" kullandım, ancak aslında "iInstanceMax" ın da varsayılan olmasını istiyorum. IMO "# [deriving (Default)]" ın yapının bir parçası olması tercih edilir, ancak alternatifin derleyiciye daha uygun olduğunu tahmin ediyorum.
Brian Oh

2
Bunun için çok teşekkürler. IMHO varsayılanlar varsayılan olmalıdır. IE. Varsayılan: varsayılan vb. Belirtmenin gerekli olduğunu düşünmüyorum. Ayrıca alanlara tanımlandıkları yerde bir değer atanabilmesi gerektiğini düşünüyorum. Bu sadece benim basit bakış açımdan ve Rust'un güvenli olacak şekilde tasarlandığını ve benimkinden çok daha geniş bir perspektif olduğunu anlıyorum. Kişi dili (veya en azından ben) öğrenirken, mevcut uygulama biraz hantal görünüyor. Rust basit bir IMHO dili değildir ve onu basitleştirmek için ne kadar çok şey yapılabilirse en azından benim için o kadar iyidir.
Brian Oh

4
DefaultBir yapı için uygularken tüm alanlar için varsayılanları tanımlamak gerekli midir?
Matthew Stevenson
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.