2024 年 Clojure 调查中分享你的想法!

欢迎!请查看 关于 页面以了解更多关于如何使用本网站的信息。

+1
Clojure

所以我自己在使用多参数函数时犯了一些错误。例如

(defn foo
  ([]
   (foo "blah"))
  ([bar]
   (println bar)))

然后我想创建另一个版本

(defn foo2
  ([]
   (foo "blah"))
  ([bar]
   (println (str "your foo is " bar)))

现在在 foo2中,我忘记调用 foo(而不是将它改为 foo2)。如果我们像调用递归中的 (recur ...) 一样,调用类似 (self ...) 不也能使事情变得容易得多吗?或者这样的东西存在而我错过了吗?

PS
这里是第一条帖子,愉快地学习 Clojure :)

2 个答案

+2

被选中
 
最佳答案

正如 Alex 指出,self 不存在,但由于 Clojure 是一个 Lisp,你可以轻易地添加这种支持。我不建议你这样做,但这很有趣。

我们将需要符号宏,它们的工作方式类似于宏,但它们(在这个例子中)是符号(我们将使用从 org.clojure/clojure.tools.macro 库的 symbol-macrolet)。

试试这个!

从命令行

clj -Sdeps '{:deps {org.clojure/tools.macro {:mvn/version "0.1.2"}}}'

一旦我们有一个 repl,我们将导入 tools.macro 库

(require '[clojure.tools.macro :refer [symbol-macrolet]])

然后,我们将定义一个新的宏,defns,它将允许你使用 self 引用函数名

(defmacro defns
 [name & args]
 `(symbol-macrolet [~'self ~name]
    (defn ~name
      ~@args)))

用法

使用defns定义函数

(defns foo
 ([] (self 2))
 ([n] (* 2 n)))

对其进行测试

user=> (foo)
4
user=> (foo 5)
10

尽管宏很有趣且易于滥用,但使用时要小心;)

感谢提供的示例!
我猜这可能可以通过宏来完成(甚至想到了`defns`命名)但尚未着手处理这方面。

我的当前解决方案是在顶部使用`(let [self function-name] ..body..)`一次,以避免编写长长的函数名:)
+1

欢迎!不,那里没有不存在的东西,你需要在那里调用foo2。

...