Frage

Ich muss gegenseitig abhängige Vars definieren. Damit meine ich, dass ein Var z. B. einen Vektor mit einem anderen var und umgekehrt. Dies wird durch den folgenden Code dargestellt:

(declare a b)
(def a [1 b])
(def b [a 2])

Aber nachdem ich diesen Code geladen habe, bekomme ich Folgendes:

test=> (first a)
1
test=> (second a)
#<Unbound Unbound: #'test/b>
test=> (first b)
[1 #<Unbound Unbound: #'test/b>]
test=> (second b)
2

Klar, so sollte es nicht funktionieren. Ich verstehe, dass das Drucken einer solchen Struktur einen Stapelüberlauf verleiht, aber ich muss sie nicht drucken. Wie soll ich das machen?

War es hilfreich?

Lösung

Sie können Folgendes machen:

(declare a b)
(def a [1 #'b])
(def b [#'a 2])

@(a 1)
=> [#'user/a 2]

Beachten Sie, dass #' ist ein Leser -Makro für die Bezugnahme auf einen VAR.

Ich bin mir immer noch nicht ganz sicher, warum Sie dies tun möchten ..... Versuch, Vars so abhängig zu machen, scheint mir ein ziemlich schlechter Code -Geruch zu sein. Es ist wahrscheinlich, dass alles, was Sie versuchen, am besten durch einen anderen Ansatz gelöst werden würde.

BEARBEITEN

Mit dem zusätzlichen Kommentar, aus dem hervorgeht, dass das Problem mit verschiedenen Arten von Entitäten zusammenhängt, die sich aufeinander beziehen, denke ich, dass ein besserer Ansatz eine Karte mit Schlüsselwörtern ist, z. B.

(def my-model
  {:a 
      {:name "Entity A" 
       :references [:b]}
   :b 
      {:name "Entity B"
       :references [:a]}}

Andere Tipps

Erstens riecht dies sehr nach einem XY -Problem.

Zweitens können sich gegenseitig referenzielle Datenstrukturen ohne Mutationszustand nicht erstellt werden. Wenn dies die Datenstruktur ist, die Sie benötigen (und Sie wahrscheinlich nicht), verwenden Sie den sehr gut gestalteten Ansatz von Clojure. Zum Beispiel:

user=> (set! *print-level* 2)  ; this is necessary to stop the infinite print recursion
2
user=> (def a (atom [1]))
#'user/a
user=> (def b (atom [a 2]))
#'user/b
user=> (swap! a conj b)
[1 #<Atom@19ed00d1: #>]
user=> @a
[1 #<Atom@19ed00d1: #>]
user=> @b
[#<Atom@5c6c2308: #> 2]

Eine faule Bewertung könnte helfen:

user=> (declare a b)
#'user/b
user=> (def a [1 (lazy-seq b)])
#'user/a
user=> (def b [(lazy-seq a) 2])
#'user/b
user=> (first a)
1
user=> (second b)
2
user=> (second a) ;stack overflow
user=> (first b) ;stack overflow
user=> (take 42 (second a)) ;still overflow as it's infinitely deep
user=> (take 42 (first b)) ;still overflow as it's infinitely deep

Hoffe es hilft, obwohl ich nicht sehen kann, wie es nützlich sein wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top