Does hinting return types in protocols have any effect within Clojure?

假装没事ソ 提交于 2020-01-02 02:35:08

问题


You can hint a return type in a protocol

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

and the compiler will make your methods comply:

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

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

But you don't have to honour the type-hint:

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

(age (new person))
; "one"

Does the type-hint have any effect?


This is a follow up to Can you specify the return type of a method in a clojure defrecord?


回答1:


The return type hint goes to the protocol function age as tag. From there, the tag is used in local type inference. To observe this in action:

- (.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

If the type hint had been left off, or if you call a method not on the hinted type, the compiler inserts a (slow) call into the reflector, instead of the plain cast:

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



来源:https://stackoverflow.com/questions/22963889/does-hinting-return-types-in-protocols-have-any-effect-within-clojure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!