Unten ist mein Code, der ein Auto-Element einer Liste (carVal)
und eine Liste (initialisiert als leer) als Parameter annimmt. Ich möchte das Element an die Liste anhängen, aber das gleiche funktioniert nicht.
Das Display zeigt die ganze Zeit eine leere Liste ()
. Kann mir jemand helfen, warum zu verstehen?
Nun, es gibt append!
als primitives Element, das die meisten Ihrer Probleme löst, wie bereits erwähnt, Schema neigt dazu, die Mutation zu missbrauchen, ist zwar möglich, wird aber normalerweise vermieden, sodass alle Prozeduren, die mutieren, ein !
haben. (genannt ein Knall) an ihrem Ende.
Auch set!
mutiert keine Daten, es ändert eine Umgebung , es macht eine Variable auf eine andere Sache, die ursprünglichen Daten bleiben unverändert.
Das Mutieren von Daten in Scheme ist ziemlich beschwerlich, aber um Ihnen meine eigene Implementierung von append! um zu sehen, wie es gemacht wird:
%Vor% Beachten Sie die Verwendung von set-cdr!
, das ein echter Mutator ist, es funktioniert nur bei Paaren, es mutiert Daten im Speicher, im Gegensatz zu 'set!'. Wenn ein Paar an eine Funktion übergeben und mit set-cdr mutiert wird! oder Set-Car !, es ist überall im Programm mutiert.
Dies gehorcht dem SRFI append! spec, die besagt, dass es variadic sein sollte und dass es beispielsweise einen undefinierten Wert zurückgeben soll.
%Vor%Was anzeigt:
%Vor%Wie sichtbar, anhängen! kann eine unendliche Anzahl von Argumenten annehmen und es mutiert sie alle bis auf die letzten.
Scheme ist vielleicht nicht die ideale Sprache für Sie. Die Verwendung von append! Wie bereits erwähnt, ist nicht standardisiert, stattdessen wird append bevorzugt, das nicht mutiert und für seinen Rückgabewert aufgerufen wird. Was ich als solches implementiere:
%Vor%Dies zeigt einen vertrauteren Scheme-Stil in Abwesenheit von Mutation, starker Rekursion und keine Verwendung der Sequenzierung.
Edit: Wenn Sie nur einige Elemente zu einer Liste hinzufügen wollen und nicht per se zwei verbinden:
%Vor%Was macht was Sie erwarten
append
erstellt eine neue Liste, sie ändert keine bestehende Liste. set!
kommen - aber selbst das wird Sie enttäuschen, da nur die lokale Bindung geändert wird. Sie müssen wirklich darüber nachdenken, welche genaue Funktionalität Sie suchen
Wenn Sie eine referenzierte Liste an Ort und Stelle mutieren möchten, müssen Sie das Äquivalent von append ausführen! (wie in den anderen Antworten erwähnt). Aber das ist gefährlich, weil Sie möglicherweise anderen Code haben, der auf der Liste zählt, die unveränderlich ist, und wenn Sie das tun werden, muss Ihr Verfahren eine haben! am Ende, um diese Gefahr zu kennzeichnen.
Eine billige Annäherung an das, was Sie tun möchten, in einem funktionaleren Stil, ist:
%Vor%Beachten Sie, dass es eine neue Liste erstellt, anfügt, das Ergebnis anzeigt und die neue Liste als Wert zurückgibt. Dies ist eine nützliche Debugging-Methode, wenn Sie keinen Zugriff auf den Zwischenwert haben: Binden Sie eine Variable, zeigen oder protokollieren Sie sie und geben Sie sie dann zurück.