indirecte opsommingen en structs

Om te beginnen wil ik zeggen dat ik me ervan bewust ben dat er veelartikelen en vragen zijn binnen SO die verwijzen naar het indirecttrefwoord in Swift.

De meest populaire verklaring voor het gebruik van indirectis om recursieve opsommingen toe te staan.

In plaats van alleen te weten wat indirectons 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 indirecthet 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 indirectintroduceert 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. indirectgebruikt 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.

  1. Het eerste stukje code zorgt ervoor dat BinaryTree<T>wordt opgeslagen door een referentie, overal waar het wordt gebruikt.

  2. Het tweede stuk code zorgt ervoor dat BinaryTree<T>alleen wordt opgeslagen door een verwijzing in het geval van node. D.w.z. BinaryTree<T>heeft over het algemeen zijn waarde direct opgeslagen, behalve in dit expliciete indirectnodegeval.


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

indirectzegt tegen compiler om de bijbehorende waarde indirect op te slaan – door verwijzing (in plaats van waarde)

  • indirect enum– wordt opgeslagen als referentie voor alle gevallen
  • indirect case– wordt alleen voor dit geval als referentie opgeslagen

Ook indirectwordt niet toegepast op andere waardetypes(struct)

Other episodes