【问题标题】:Clojure: named anonymous functionClojure:命名匿名函数
【发布时间】:2017-01-16 19:25:17
【问题描述】:

在 Clojure 中,何时以及为什么要使用命名匿名函数?例如,

((fn add-five [x] (+ x 5)) 3))

在 ClojureDocs 中,one example's comment 表示它在堆栈跟踪中很有用。能举个例子吗?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    命名匿名函数有两个原因(或者至少有两个我这样做的原因)。首先是给它起一个名字可以告诉后来的读者(可能是你自己 6 个月后)匿名函数到底应该做什么。

    第二个是(正如您提到的)在堆栈跟踪中提供更好的信息,以便在发生故障时将您指向代码中的正确位置。函数被编译成类,并且类名包括函数名的(munged)版本。当您有堆栈跟踪时,它将包含该类名,从而在语义上将您指向正确的位置。

    user=> (filter (fn [x] (/ 100 x)) [100 50 0])
    ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:158)
    user=> (pst *e)
    ArithmeticException Divide by zero
        clojure.lang.Numbers.divide (Numbers.java:158)
        clojure.lang.Numbers.divide (Numbers.java:3784)
        user/eval8/fn--9 (NO_SOURCE_FILE:3)
        clojure.core/filter/fn--6908 (core.clj:2790)
        ...
    nil
    
    user=> (filter (fn hundred-div [x] (/ 100 x)) [100 50 0])
    ArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:158)
    user=> (pst *e)
    ArithmeticException Divide by zero
        clojure.lang.Numbers.divide (Numbers.java:158)
        clojure.lang.Numbers.divide (Numbers.java:3784)
        user/eval14/hundred-div--15 (NO_SOURCE_FILE:5)        ;; <---
        clojure.core/filter/fn--6908 (core.clj:2790)
        ...
    

    【讨论】:

      【解决方案2】:

      除了在堆栈跟踪中有用之外,我想您可以在需要匿名函数递归时使用它,因为它可以调用自己。

      例如:

      (fn factorial[n]
        (if (<= n 1)
          1
          (* n  (factorial (- n 1)))))
      

      虽然在 Clojure 中这样的递归有点危险,因为它可能会导致堆栈溢出。

      【讨论】:

        【解决方案3】:

        命名的匿名函数在引用自己时很有用,也可以打印出他们的名字:

        user=> ((fn [] (throw (Exception. "unnamed"))))
        
        Exception unnamed  user/eval805/fn--806 (NO_SOURCE_FILE:1)
        user=> ((fn myfn [] (throw (Exception. "named"))))
        
        Exception named  user/eval809/myfn--810 (NO_SOURCE_FILE:1)
        

        【讨论】:

          猜你喜欢
          • 2020-01-03
          • 1970-01-01
          • 2011-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多