【问题标题】:Does hinting return types in protocols have any effect within Clojure?协议中的提示返回类型在 Clojure 中是否有任何影响?
【发布时间】:2014-04-09 13:22:12
【问题描述】:

您可以在协议中提示返回类型

(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?的跟进

【问题讨论】:

  • 类型提示错位。应该像(age ^String [this] "one")。编译器使方法符合要求。
  • 令人困惑,但是在您拥有的方法名称上,它是 defrecord 中类型提示的正确位置(请参阅文档)。我不知道 defprotocol 中有一个正确的位置,因为那里的非原始提示似乎被忽略了,而原始提示似乎破坏了实现它们的能力。我已经删除了我的回答,充其量是推测性的。
  • @A.Webb 感谢您的努力。我倾向于将这个问题作为路标,警告困惑的人,包括我自己。

标签: clojure


【解决方案1】:

返回类型提示作为标记转到协议函数age。从那里,标签用于本地类型推断。观察实际情况:

- (.longValue (age (new person))) ClassCastException java.lang.String cannot be cast to java.lang.Integer net.bendlas.lintox/eval18038 (form-init4752901931682060526.clj:1) ;; longValue is a method of Integer, so a direct cast has been inserted

如果类型提示已被忽略,或者如果您调用的方法不在提示的类型上,编译器会在反射器中插入一个(慢速)调用,而不是简单的强制转换:

- (.otherMethod (age (new person))) IllegalArgumentException No matching field found: otherMethod for class java.lang.String clojure.lang.Reflector.getInstanceField (Reflector.java:271)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 2016-12-06
    • 2012-05-29
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多