Vraag Wat is het verschil tussen loop en while true?


De Rust-zelfstudie en nu boek beweren dat er een verschil is tussen while true en loop, maar dat het in dit stadium niet zo belangrijk is om het te begrijpen.

Als je een oneindige lus nodig hebt, kom je misschien in de verleiding om dit te schrijven:

while true {

Rust heeft echter een speciaal trefwoord, loop, om deze zaak af te handelen:

loop {

Rust's controle-flow analyse behandelt dit construct anders dan een tijdje waar, omdat we weten dat het altijd zal lussen. De details van wat dat betekent zijn niet super belangrijk om te begrijpen in dit stadium, maar in het algemeen, hoe meer informatie we kunnen geven aan de compiler, hoe beter het kan doen met veiligheid en het genereren van codes, dus je zou altijd de voorkeur moeten geven aan loop wanneer je plan om oneindig te lussen.

Nadat ik een klein beetje compiler-type werk heb gedaan, moet ik me afvragen welk mogelijk semantisch verschil er is, omdat het voor de compiler onbelangrijk zou zijn om erachter te komen dat beide een oneindige lus zijn.

Dus, hoe behandelt de compiler ze anders?


20
2018-03-06 04:28


oorsprong


antwoorden:


Dit werd beantwoord reddit. Zoals je al zei, kon de compiler speciaal geval zijn while true, maar dat doet het niet. Aangezien dit niet het geval is, wordt door de compiler niet semantisch afgeleid dat een niet-opgegeven variabele die is ingesteld in a while true loop moet altijd worden geïnitialiseerd als je uit de lus breekt, terwijl dat wel het geval is voor een loop lus:

Het helpt ook de reden van de compiler over de loops, bijvoorbeeld

let x;
loop { x = 1; break; }
println!("{}", x)

is perfect geldig, terwijl

let x;
while true { x = 1; break; }
println!("{}", x);

kan niet compileren met "gebruik van mogelijk niet-geïnitialiseerde variabele" wijzend op de x in de println. In het tweede geval detecteert de compiler niet dat de body van de lus altijd minstens één keer zal worden uitgevoerd.

(Natuurlijk kunnen we het construct speciaal vermelden while true om te doen alsof loop doet het nu. Ik geloof dat dit is wat Java doet.)


17
2018-03-06 04:39



Het eerste wat te zeggen is, is dat deze qua prestaties waarschijnlijk identiek zijn. Terwijl Rust zelf niets bijzonders doet while true, LLVM maakt die optimalisatie waarschijnlijk wel. De Rust-compiler probeert de dingen eenvoudig te houden door optimalisaties naar LLVM te delegeren waar dat mogelijk is.

in het algemeen geldt dat hoe meer informatie we aan de compiler kunnen geven, des te beter het kan zijn met veiligheid en het genereren van code

Hoewel bepaalde constante uitdrukkingen mogelijk door LLVM worden weggeoptimaliseerd, verandert de semantiek van de taal niet of een uitdrukking constant is of niet. Dit is goed, want het helpt mensen ook redeneren over code.

Daarom true is een simpele uitdrukking, we weten dat het constant is. En zo is het ook true != false en [0; 1].len() == 1. Maar hoe zit het met num_cpus::get() == 1? Ik weet eigenlijk niet of er compilatiedoelen zijn waar dat constant zou kunnen zijn, en ik zou er ook niet over hoeven na te denken!

De fout in het voorbeeld van telotortium zou significanter zijn in combinatie met gegenereerde code of macro's. Stel je een macro voor die soms resulteert in een eenvoudige statische expressie zoals true == true, maar somsverwijst naar een variabele of roept een functie aan. Soms kan de compiler vaststellen of de lus één keer wordt uitgevoerd, maar soms kan dit niet. In Rust nu, zal de fout in dat voorbeeld altijd een fout zijn, ongeacht welke code is gegenereerd voor die voorwaarde. Geen verrassingen.


2
2018-04-09 18:17



Wat is het verschil tussen loop en while true?

Je zou kunnen vragen wat het verschil is tussen for en while? Het antwoord zal dicht bij: Wat is een programmeertaal?

Wanneer je schrijft while condition {}, je zegt "terwijl conditie waar is, doe dat", maar we kunnen zien dat zeggen "terwijl waar waar is, doe dat", overbodig is. Dit is waar loop komt van, het kan heel goed oneindige lussen uitdrukken omdat we "lus daarop" zeggen. We hebben geen enkele voorwaarde, dit is beter.

Dus, hoe behandelt de compiler ze anders?

Ik kan de vraag 'hoe' niet beantwoorden, maar ik veronderstel dat je wilt weten 'waarom'. Hiermee kan de compiler weten dat deze lus minstens één keer zal worden uitgevoerd, zoals de do {} while (condition); van C. De compiler kan deze informatie gebruiken om betere code of waarschuwingen te produceren. Bovendien weet je zeker dat de lus zal worden uitgevoerd waar een while loop zou weg kunnen zijn omdat de compiler hem op afstand optimaliseert. Het leuke is dat Rust intern gebruikmaakt van LLVM, en het lijkt erop dat LLVM geen manier heeft om een ​​oneindige lus uit te drukken, dus het produceert bugs in sommige gevallen.


0
2018-04-09 19:35