Om te beginnen wil ik zeggen dat ik me ervan bewust ben dat er veelartikelen en vragen zijn binnen SO die verwijzen naar het indirect
trefwoord in Swift.
De meest populaire verklaring voor het gebruik van indirect
is om recursieve opsommingen toe te staan.
In plaats van alleen te weten wat indirect
ons toestaat te doen, zou ik graag willen weten hoehet ons in staat stelt recursieve opsommingen te gebruiken.
Vragen:
Is het omdat opsommingen waardetypen zijn en waardetypen niet goed schalen als ze in een recursieve structuur zijn gebouwd? Waarom?
Wijzigt indirect
het gedrag van het waardetype om zich meer als een referentietype te gedragen?
De volgende twee voorbeelden compileren prima. Wat is het verschil?
indirect enum BinaryTree<T> {
case node(BinaryTree<T>, T, BinaryTree<T>)
case empty
}
enum BinaryTree<T> {
indirect case node(BinaryTree<T>, T, BinaryTree<T>)
case empty
}
Antwoord 1, autoriteit 100%
Het trefwoord indirect
introduceert een indirecte laag achter de schermen.
Je geeft aan dat een opsommingsgeval recursief is door er indirect voor te schrijven, wat de compiler vertelt om de benodigde laag indirecte in te voegen.
Van hier
Het belangrijkste van structs en opsommingen is dat ze een constante grootte hebben. Het rechtstreeks toestaan van recursieve structuren of opsommingen zou dit schenden, aangezien er een onbepaalbaar aantal recursies zou zijn, waardoor de grootte niet constant en onvoorspelbaar zou zijn. indirect
gebruikt een referentie van constante grootte om te verwijzen naar een instantie van opsomming van constante grootte.
Er is een verschil tussen de twee codefragmenten die u laat zien.
-
Het eerste stukje code zorgt ervoor dat
BinaryTree<T>
wordt opgeslagen door een referentie, overal waar het wordt gebruikt. -
Het tweede stuk code zorgt ervoor dat
BinaryTree<T>
alleen wordt opgeslagen door een verwijzing in het geval vannode
. D.w.z.BinaryTree<T>
heeft over het algemeen zijn waarde direct opgeslagen, behalve in dit explicieteindirect
node
geval.
Antwoord 2
Snelle indirecte opsomming
Sinds Swift v2.0
Swift Enum[Over]is een waardetype[Over], en we wijzen het toe dat de waarde wordt gekopieerd, daarom moet de grootte van het type worden berekend tijdens het compileren.
Probleem met geassocieerdewaarde
enum MyEnum { //Recursive enum <enum_name> is not marked
case case1(MyEnum) `indirect`
}
het is niet mogelijk om de uiteindelijke grootte te berekenen vanwege recursie
indirect
zegt tegen compiler om de bijbehorende waarde indirect op te slaan – door verwijzing (in plaats van waarde)
indirect enum
– wordt opgeslagen als referentie voor alle gevallenindirect case
– wordt alleen voor dit geval als referentie opgeslagen
Ook indirect
wordt niet toegepast op andere waardetypes(struct)