高阶函数的Clojure类型提示

我正在创建一个小应用程序来学习Clojure,并且我为代码启用了反射功能的警告,并且我发现了许多可以添加类型提示以丰富我的代码并提高性能的地方。

然而,我从我的代码中的几个地方得到警告,我使用的是高阶函数或简短的匿名语法表示法,我不知道如何在不扩展函数定义的情况下修复这些情况。

例如,请考虑以下代码:

(deftest test-java-expenses
    (testing "Testing Expenses"
        (let [total-cents (map (memfn amountInCents) expenses)]
            (is (= 7406 (apply + total-cents))))))

expenses是包含某些类型/类名为Expense对象的向量。

看起来投诉是关于amountInCents ,Clojure使用反射来传递参数来确定他们的类型(即Expense )。

我可以修改(fn [^Expense e] (.amountInCents e)) (memfn amountInCents)来修正警告,但这只会让我的代码更难阅读,在我看来,它不够优雅。

如果我有这样的事情,我会遇到同样的问题: #(.amountInCents %)使用匿名函数声明的特殊语法。

我还考虑使用一个带注释的函数来创建费用对象,其返回类型标有它的类型,希望稍后可以推断出类型,如下所示

(defn new-expense ^Expense [date-string dollars cents category merchant-name]
    (Expense. date-string dollars cents category merchant-name))

然后创造我的开支做:

(def expenses [(new-expense "2009-8-24" 44 95 "books" "amazon.com")
               (new-expense "2009-8-25" 29 11 "gas" "shell")])

但那也没有用; 编译器仍然不会推断所讨论的矢量是Expense对象的矢量。

有没有办法解决像上面那些使用#()情况下的反射警告,或者我将一个函数作为参数传递给高阶函数(例如memfn )的其他情况? 我的意思是,一种无需自己扩展函数声明的方法(例如(fn [^Type n] ....)


你只需要在memfn调用中添加一个类型提示?

memfn文档(其中memfn被描述为(memfn name & args) ):

name可以用方法接收者的类型进行类型提示以避免反射呼叫。

所以在你的情况下,你可以使用:

(memfn ^Expense amountInCents)

避免反思。

链接地址: http://www.djcxy.com/p/82575.html

上一篇: Clojure Type Hints for High Order Functions

下一篇: Extending support for jsonb with clojure.jdbc and clojure/data.json