【问题标题】:Clojure: multiple type hints?Clojure:多种类型提示?
【发布时间】:2015-03-18 19:06:07
【问题描述】:

如何给一个变量指定两种类型的可能性?

(defn connect! [(or ^:String :^java.net.InetAddress) host ^:Integer port] ...)

谢谢!

【问题讨论】:

  • 您为什么要这样做?类型提示的目的是让编译器避免反射。允许一个表单被类型提示为两个不同的类会破坏这个目的。

标签: clojure clojure-java-interop


【解决方案1】:

来自Clojure documentation

Clojure 支持使用类型提示来帮助编译器避免在代码的性能关键区域中进行反射。通常,应该避免使用类型提示,直到出现已知的性能瓶颈

类型提示的目的是让编译器避免反射。类型提示代码的任何自文档方面都是次要的。当您说出以下内容时:

(defn connect! [^String host])

您要告诉编译器的是在编译时将host 上的所有Java 互操作方法调用解析为String 类上的方法调用。允许使用多个类来提示表单会破坏这个目的 - 编译器不会知道将方法调用编译为哪个类。即使是这样,一个对象也不能同时是StringInetAddress,因此如果发生InetAddress,任何针对String 类编译的方法调用都将保证以ClassCastException 失败传入,反之亦然。

【讨论】:

  • 我想到了自我文档,但是是的,我想这可以通过文档字符串来实现。谢谢。
  • @leontalbot 如果您还没有,请查看Prismatic schema,了解支持联合和运行时验证的自记录函数定义。
【解决方案2】:

据我所知,唯一的方法是自己检查并在 let 中添加提示:

(condp instance? host
  String (let [^String s] (...))
  InetAddress (let [^InetAddress a] (...)))

【讨论】:

  • 这行得通,但我会将其视为一种代码异味 - 它请求使用协议或多方法进行重构。
猜你喜欢
  • 2017-07-27
  • 2020-01-17
  • 2011-06-22
  • 1970-01-01
  • 2015-11-14
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
相关资源
最近更新 更多