clojure - 协议(protocol)中的提示返回类型在 Clojure 中是否有任何影响?

标签 clojure

您可以在协议(protocol)中暗示返回类型

(defprotocol Individual
  (^Integer age [this]))

编译器将使您的方法符合:

(defrecord person []
  Individual
  (^String age [this] "one"))

; CompilerException java.lang.IllegalArgumentException: Mismatched return type: age, expected: java.lang.Object, had: java.lang.String, ...

但是您不必遵守类型提示:

(defrecord person []
  Individual
  (age [this] "one"))

(age (new person))
; "one"

类型提示有什么作用吗?

<小时/>

这是 Can you specify the return type of a method in a clojure defrecord? 的后续内容

最佳答案

返回类型提示作为标记发送到协议(protocol)函数age。从那里,该标签用于本地类型推断。要观察其实际情况:

- (.longValue(年龄(新人))) ClassCastException java.lang.String 无法转换为 java.lang.Integer net.bendlas.lintox/eval18038(form-init4752901931682060526.clj:1) ;; longValue 是 Integer 的方法,因此插入了直接强制转换

如果类型提示已关闭,或者如果您调用的方法不在提示类型上,则编译器会在反射器中插入一个(缓慢的)调用,而不是普通的强制转换:

- (.otherMethod(年龄(新人))) IllegalArgumentException 找不到匹配字段:类 java.lang.String clojure.lang.Reflector.getInstanceField 的 otherMethod (Reflector.java:271)

关于clojure - 协议(protocol)中的提示返回类型在 Clojure 中是否有任何影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22963889/

相关文章:

networking - 如何在 Clojure 中懒惰地阅读网页

javascript - cljs Om 与 React 组件互操作?

testing - 在 Clojure 中为测试定义函数

android - 如何在 Android Studio 中使用 Cursive 构建 Android 应用

clojure - lein REPL服务器启动超时

java - Clojure 列出 uberjar 资源中的子文件夹

clojure - leiningen 为什么要建立目录层次结构?我可以放弃它吗?

vector - 相交两个先验排序向量的惯用/高效Clojure方法?

clojure - 在 Clojure 中按分隔符分割序列?

clojure - 如何在 clojure 中编写 java varg 函数?