J'ai écrit une fonction pour interroger un petit programme de base de données que j'écris pour l'école. Cette fonction recherche par nom. Lorsque j'exécute la fonction seule, cela fonctionne. Lorsque je l'exécute dans le menu, cela ne fonctionne pas (il renvoie NIL). Voici tout ce qui est pertinent:
(defun prompt-read (prompt) (format *query-io* "~a: " prompt) (force-output *query-io*) (read-line *query-io*)) (defun search-name (name) (remove-if-not #'(lambda (cat) (equal (getf cat :name) name)) *db*)) (defun input-name () (search-name (prompt-read "Name"))) (defun search-menu () (print "1) Search Name") (print "2) Search Color") (print "3) Search Min. Weight") (print "4) Search Min. Experience") (print "5) Search Min. Length") (setf choose (read)) (cond ((= choose 1)(input-name)) ((= choose 2)(print "Color")) ((= choose 3)(print "Weight")) ((= choose 4)(print "XP")) ((= choose 5)(print "Color")) ) NIL )
Pour le moment, je travaille uniquement à faire fonctionner la recherche par nom, le reste du menu n'est que des espaces réservés. Lorsque j'exécute "input-name" (qui utilise search-name) par lui-même, il renvoie le résultat correct. Lorsque j'essaie la première option du menu de recherche (qui exécute également "nom-d'entrée"), elle renvoie NIL. Je me demande pourquoi lorsque je l'exécute tout seul fonctionne, mais pas lorsqu'il est utilisé avec ce menu. Si quelqu'un a besoin d'autres informations, n'hésitez pas à demander. Je ferai de mon mieux pour le fournir. De plus, je suis un débutant, alors pardonnez-moi.
3 Réponses :
J'ai fini par trouver une solution qui fonctionne en utilisant simplement print dans la fonction input-name. Cette fonction n'a qu'à afficher les résultats donc cela fonctionne très bien.
(defun input-name () (print (search-name (prompt-read "Name"))))
Même fonction qu'avant mais avec une impression ajoutée. Maintenant, cela fonctionne également dans le menu.
Mais maintenant, lorsque vous exécutez la fonction seule, le résultat est imprimé deux fois. Comprends-tu pourquoi?
@RainerJoswig ouais, c'est bien. Ce n'est qu'un projet pour débutant et tout ce que j'ai à faire est d'afficher les bons résultats à l'écran.
La question était: comprenez-vous pourquoi il est imprimé deux fois?
Et j'ai dit «ouais».
Si vous voulez une sortie dans un programme, alors vous devez imprimer quelque chose.
(defun foo () (let ((bar 10)) ; define BAR (print bar) ; BAR is defined (setf bar 20) ; BAR is defined (print bar))) ; BAR is defined
La fonction ci-dessus n'imprime rien. Il renvoie juste un nombre.
Si nous l'appelons dans la boucle read-eval-print-loop:
(defun foo () (setf bar 10) ; <- BAR is undefined (print bar) ; <- BAR is undefined (setf bar 20) ; <- BAR is undefined (print bar)) ; <- BAR is undefined
Vous voyez que 1000 est imprimé. Mais pourquoi?
Nous l'exécutons dans le READ-EVAL- PRINT -LOOP. La boucle read, eval, PRINT .
Signifie: le système Lisp imprime la valeur renvoyée de l'évaluation, mais pas votre code.
Maintenant nous ajoutons un appel print :
CL-USER 138 > (defun call-the-example () (example) (values)) CALL-THE-EXAMPLE CL-USER 139 > (call-the-example) 1000
Il est imprimé deux fois!
CL-USER 137 > (example) 1000 ; <- the function example prints 1000 ; <- the read-eval-print-loop prints the result
Donc notre fonction imprime maintenant quelque chose lui-même, car il appelle PRINT
.
Maintenant cela fonctionne:
CL-USER 136 > (defun example () (print 1000)) EXAMPLE CL-USER 137 > (example) 1000 1000
Nous pouvons appeler le exemple
, la fonction imprime quelque chose et le REPL n'imprime rien.
Le REPL n'imprime rien, puisque call-the-example
ne renvoie rien. Il ne renvoie aucune valeur.
Vous devez donc ajouter un appel PRINT
Vous avez raison d'ajouter un appel d'impression, mais la raison est simplement qu'avant vous n'avez pas imprimé et l'appel à (nom-d'entrée)
ne s'est pas imprimé. Vous appeliez (input-name)
dans la READ-EVAL-PRINT-LOOP, qui imprime ensuite le résultat. Pas votre code, mais le REPL a produit la sortie.
Style: variable non définie
CL-USER 134 > (defun example () 1000) EXAMPLE CL-USER 135 > (example) 1000
Écrivez ceci à la place - en utilisant LET
pour définir une variable locale:
(defun example () 1000)
search-menu
ne fait rien avec la valeur de retour de input-name
. Une fonction renvoie la valeur de la dernière expression qu'elle exécute, et la dernière expression dans search-menu
est NIL
, c'est donc ce qu'elle renvoie.
Si vous voulez pour renvoyer la valeur de l'expression cond
, supprimez NIL
de la fin.
Vous devez également utiliser let
pour déclarer une variable locale, plutôt que d'affecter la variable non définie choose
.
(defun search-menu () (print "1) Search Name") (print "2) Search Color") (print "3) Search Min. Weight") (print "4) Search Min. Experience") (print "5) Search Min. Length") (let ((choose (read))) (cond ((= choose 1) (input-name)) ((= choose 2) (print "Color")) ((= choose 3) (print "Weight")) ((= choose 4) (print "XP")) ((= choose 5) (print "Color")))))
Je ne comprends pas la question. Vous devrez peut-être nous montrer une interaction. Comme la fonction
search-menu
est actuellement, elle renvoie toujoursNIL
, puisque c'est la dernière valeur explicitement dans votre code - voir l'avant-dernière ligne desearch- menu
. Comment peut-il renvoyer autre chose queNIL
?De plus: la variable
choose
n'est pas définie dans votre code.setf
ne définit pas les variables - il ne fait que les définir.Astuce: essayez de comprendre la différence entre imprimer quelque chose dans une fonction , renvoyer une valeur d'une fonction et imprimer le résultat de l'évaluation dans un READ-EVEL-PRINT- BOUCLE .