Shadowing is de mogelijkheid om een variabele met dezelfde naam meerdere keren te declareren in hetzelfde bereik, waarbij de nieuwe variabele de vorige "schaduwt". In talen zonder shadowing (C, C++) leidt het opnieuw definiëren van een variabele tot een fout of onbepaald gedrag. Rust staat shadowing toe, en elke variabele is een onafhankelijk object met een nieuw type of waarde. Dit is handig bij stapsgewijze transformaties van waarden — bijvoorbeeld, een string direct omzetten naar een nummer zonder nieuwe namen te bedenken.
Probleem: enerzijds verbetert het de leesbaarheid en voorkomt het de uitbreiding van variabelenamen; anderzijds kan het debuggen moeilijker zijn als je per ongeluk een variabele in een complex blok "schaduwt" en een onverwacht resultaat krijgt.
Oplossing: Shadowing wordt alleen gebruikt daar waar het daadwerkelijk de transformatie vergemakkelijkt en de leesbaarheid niet vermindert. Elke "let var = ...;" creëert een nieuwe variabele, terwijl de oude ongewijzigd blijft buiten het declaratieblok.
Codevoorbeeld:
fn example() { let x = "42"; let x = x.parse::<i32>().unwrap(); println!("x: {}", x); // x: 42 }
Belangrijkste kenmerken:
Kan shadowing de mutabiliteit van een variabele wijzigen?
Ja, je kunt een niet-mutable variabele schaduwen met een mutable en vice versa:
let x = 5; let mut x = x; x += 1;
Betekent shadowing dat de vorige variabele is vernietigd?
Nee, de waarden van de vorige variabele blijven bestaan totdat het blok waarin ze zijn gedeclareerd eindigt, maar zijn niet meer toegankelijk via de naam.
Kan je shadowing gebruiken binnen een lus of binnen geneste blokken?
Ja, elk bereik (scope) staat het declareren van variabelen met dezelfde namen toe, en dit zijn verschillende variabelen.
In de functie is er let result = expr1; ... let result = expr2;, waar de types verschillen.
Voordelen:
Nadelen:
Shadowing wordt alleen gebruikt voor het wijzigen van het type: eerst wordt een string geparsed, daarna — een numerieke toewijzing.
Voordelen:
Nadelen: