WebHU - Programozási kérdések és válaszok

Hogyan köthetek változót egy illesztési karban, ha egy változó hivatkozáson egyeztetek?

matchegy szerkezeten dolgozom, és gyufaőrt szeretnék használni. A struktúra azonban változtatható, és úgy tűnik, hogy az illesztőkar bal oldalán lévő kötési változók külön kölcsönzést okoznak. Ez azután fordítási hibákat vált ki, mivel nem kaphat második kölcsönzést (változatlan vagy megváltoztathatatlan), amíg a módosítható kölcsön még fennáll.

struct A(u8);

impl A {
    fn is_awesome(&self) -> bool { true }
}

struct Container(A);

impl Container {
    fn update(&mut self) {}

    fn do_a_thing(&mut self) {
        match *self {
            Container(ref a) if a.is_awesome() => self.update(),
            _ => {},
        }
    }
}

fn main() {}
error[E0502]: cannot borrow `*self` as mutable because `self.0` is also borrowed as immutable
  --> src/main.rs:14:51
   |
14 |             Container(ref a) if a.is_awesome() => self.update(),
   |                       -----                       ^^^^ mutable borrow occurs here
   |                       |
   |                       immutable borrow occurs here
15 |             _ => {},
16 |         }
   |         - immutable borrow ends here

Jelenlegi megoldásom az, hogy megkettőzöm a logikát a meccsőr kiszámításához a meccsem előtt, majd a logikai értéket használhatom meccsőrként. Ez nem elégíti ki a nyilvánvaló kódduplikációs problémákat:

fn do_a_thing(&mut self) {
    let awesome = match *self {
        Container(ref a) => a.is_awesome(),
    };

    match *self {
        Container(..) if awesome => self.update(),
        _ => {},
    }
}
17.04.2015

  • match self { &mut Container(ref a) => … } átírnám let a = &self.0; …-ra, magam. 17.04.2015
  • @ChrisMorgan igen, én is. Belegondolás a mintaillesztés használata enum vagy más beágyazott réteg hozzáadása nélkül, hogy a példa kicsi legyen. 17.04.2015
  • (Az uralkodó stílus ilyen esetekben is a match *self { Container(ref a) => … }, hogy az elágazási minták helyett az egyezés tárgyában lévő hivatkozásokat vegyük ki.) 17.04.2015
  • @ChrisMorgan jó fogás, ez maradt a járóki próbáimból! 17.04.2015

Válaszok:


1

Ha a nem lexikális élettartam engedélyezve van, az eredeti kód a jelenlegi állapotában működik.

A nem lexikális élettartamok előtt

A biztonság jegyében a Rust tiltja a dolgok különféle osztályait, még akkor is, ha ezek egy konkrét esete működhet. Ez az egyik ilyen eset, és amit próbálsz, az nem és soha nem is lesz lehetséges.

Létrehozott egy hivatkozást a self tartalmára, de ezután meghívja a self.update()-t, amely változó hivatkozást akar a self-ra. Egy nyelv hatékonyan beillesztheti update, és így megállapíthatja, hogy biztonságos a hivatkozás életben tartása, de könnyen bebizonyítható, hogy az alapkoncepció nem mindig működik a rossz példával, amelyet a Rust fordító ment meg. tól től:

struct A(u8);

struct Container(A);

impl Container {
    fn update(&mut self) {
        self.0 = A(0);
    }

    fn do_a_thing(&mut self) {
        let a = &self.0;
        let before = a.0;
        self.update();
        assert_eq!(before, a.0);
    }
}

fn main() {
    Container(A(1)).do_a_thing();
    // Panic: 1 != 0
}

Ha ezt engedélyeznék a fordításhoz, pánikba esne, mert a a célpontja annak ellenére, hogy megváltoztathatatlan hivatkozás, megváltozott alattad, amit nyilvánvalóan nem szabad megengedni.

A C++ sablonok jókedvű mentalitása jó példa arra, hogy megpróbálunk valamit, ami működhet vagy nem; nagyon is lehetséges velük, hogy egy függvény belsejében végbemenő mélyreható változás megtöri a felhasználókat úgy, hogy többé nem fordítanak le. Rust úgy döntött, hogy nem megy ezen az úton, ezért minden módszert erős elszigetelő gátként kezel. A függvény törzsében végrehajtott változtatások soha nem okozzák a metóduson kívüli kód fordításának leállítását.

A self &mut self-kérő metódusának meghívása közben nem hivatkozhat semmire, akár változtatható, akár más módon.

17.04.2015
  • Meglehetősen nézeteltéréseim voltak a Rust fordítóval arról, hogy mit szabad és mit nem szabad megtennem. A rustc-vel vitatkozni kicsit bosszantó, mert sosem nyerem meg a vitát. Ha elég hosszan gondolkodom, mindig találok okot arra, hogy amit akartam, az rossz. 17.04.2015
  • Egyáltalán nem haragszom a fordítóra, és teljesen egyetértek az indoklással. Ideális esetemben azt szerettem volna, ha egy változót kötök a gyufakar bal oldalán, és a kötés valahogy kikerül a hatókörből, mielőtt a gyufatörzs elindulna. Ez lehetővé tette volna, hogy meghívjam a metódusomat a meccsőrben, de még mindig egy szinttel feljebb mutassak a kötött változóhoz képest. 17.04.2015
  • Gondolom, nincs tisztább megoldása, mint a jelenlegi megoldásom? 23.04.2015
  • Nem, ne félj, amíg még mindig lexikális kölcsönzéseket használunk. 24.04.2015
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..