请在 2024 Clojure 状态调研! 分享您的想法。

欢迎!欲了解更多关于本网站如何运作的信息,请参阅关于 页面。

0
Clojure

Python 有一种名为装饰器的数据结构,允许在不修改资源结构的情况下更改功能。如果您需要在运行时更改行为,这非常有帮助。

一些参考资料
https://www.pythonlang.cn/dev/peps/pep-0318/
https://www.datacamp.com/community/tutorials/decorators-python

我在网上搜索了一下,没有发现任何与此类似的数据结构。有其他资源可以利用以达到同样的效果吗?

谢谢!

2 个答案

+2

装饰器并不是一种数据结构。它仅仅是为了让某些代码更易于阅读而实现的一种不必要的语法糖,仅此而已。
除非您依赖于全局变量或引入其他引用模糊性,否则您无法在运行时使用它们来更改某个内容。

话虽如此,在将函数视为一等公民的任何语言中,都有一种方法可以实现完全相同的功能,但可能没有某些特殊糖。

您链接的教程给出了以下示例

@split_string
@uppercase_decorator
def say_hi():
    return 'hello there'

在Clojure中实现它的最相似方式可能是这样的

(def say-hi (comp
             split-string 
             uppercase-decorator
             (fn [] "hello there")))

尽管我可能只将其全部封装在一个函数中,这在Clojure中更为简单,因为Clojure中没有像Python那样的出现在任何地方的可能性的`return`语句。

(defn say-hi []
  (-> "hello there"
    uppercase-decorator
    split-string))
0

我完全同意Eugene的看法。为了完整性起见,我想补充一点,你也可以编写一个可以模拟预期行为的宏。

(defmacro with-decorators
  [decorators fname & body]
  `(def ~fname (comp ~@(reverse decorators) (fn ~@body))))

(require '[clojure.string :as s])

(with-decorators
  ;; decorators
  [s/upper-case #(s/split % #"\s+")]
  ;; function definition as in `defn`
  say-hi []
  "hello there")

(say-hi)
;; => ["HELLO" "THERE"]
...