39

私はClojureで単純だがイライラする問題を抱えています.ユーザーが自分の入力から何をしたいのかを理解し、それを行う別の関数を呼び出す関数(それを読み取り関数と呼びましょう)があります(アクション関数と呼びましょう). このアクション関数は、完了時に読み取り関数を呼び出して、ユーザーが別のタスクを実行できるようにします。

ここで私の問題は、read-function のコードを action-function のコードの前に置くと、read-function で、action-function が何であるかがわからないというエラーが発生することです (そのコードはさらにdown) 反対のことをすると、明らかに同様のエラーが発生し、read-function を解決できないなどのメッセージが表示されます。

これを修正する簡単な方法はありますか?

実際のコード:

(defn ajout [botin]
  (def botin botin)
  (readCmd botin)
)

(defn readCmd [botin]
  (println "Entrez une commande svp ")
  (def botin botin)
  (let [cmd (read-line)]
    (if (.equals cmd "a") ((println "Ajout 8o") (ajout botin))
      (if (.equals cmd "e") ((println "Elim 8o") (eliminer botin))
        (if (.equals cmd "i") ((println "Imprim 8o") (imprimer botin))
          ((println "Commande invalide, nous vous rapellons que les commandes possibles sont : ") (print-les-cmd) (readCmd))))))


)

このように、ajout 関数の (readCmd botin) 行で次のようなエラーが表示されます: Unable to resolve symbol: readCmd in this context

これら 2 つの関数のコードを逆の順序で配置すると、次のようなエラーが表示されます: Unable to resolve symbol: ajout in this context

4

4 に答える 4

65

Clojure では前方宣言を使用できるため、まだ定義されていない関数を呼び出すことができます。

(declare readCmd)

動作するはずです!

Clojure では、関数を定義する順序が重要です。関数は、まだ定義されていない別の関数 (またはその他の関数) を呼び出すことはできません。そのため、前方宣言があります。

于 2009-07-13T10:47:16.967 に答える
18

他の人がすでに答えているように、差し迫った問題を解決するには(readCmdを宣言する)必要があります。

ただし、このコードにはまだ問題があります。実際には相互再帰 (readCmd -> ajout -> readCmd -> imprimer -> readCmd -> ...) を使用して反復プロセスを実装しているため、スタックを消費し、( on) スタック オーバーフロー。これを整理するより良い方法は、readCmd の末尾を再帰的にして、アクションを呼び出すようにすることです。アクションが戻ると、readCmd tail は再帰的に自分自身を呼び出します。

また、このコード スニペット:

((println "Ajout 8o") (ajout botin))

おそらくあなたがやりたいことではありません.printlnを呼び出し、結果を関数として使用しようとします. 代わりに "do" を使用してください:

(do (println "Ajout 8o") (ajout botin))

case または cond について読むことも検討してください。ネストされた if を単純化します。

あなたのコードのもう一つの奇妙な点は

(def botin botin)

それは何についてですか?

于 2009-07-20T11:48:22.657 に答える
11

コードの先頭に次のように入力します。

(declare readCmd)
于 2009-07-12T21:12:12.920 に答える