可空双重类型提示

时间:2016-06-29 12:46:20

标签: clojure nullable type-hinting

我正在编写一个神经网络,并且具有以下节点定义:

(defrecord Node [^double input-sum ^double last-output])

input-sum是它输入的运行总和;预激活。 last-output是激活的值。

我最初的想法是创建一个像(->Node 0 nil)这样的初始节点。我的理性是,在last-output被激活之前给它一个真正的价值是没有任何意义的。

不幸的是,创建上述节点会产生NPE;显然是因为它试图将nil作为双重投射:

(->Node 0 nil)
NullPointerException   clojure.lang.RT.doubleCast (RT.java:1298)

如果我删除last-output上的类型提示,它就可以正常工作。

我正试图养成一种暗示我能做什么的习惯。有没有办法在last-output上提供类型提示,但也表明nil是可接受的值?

2 个答案:

答案 0 :(得分:3)

如果你真的需要使用基本类型输入提示,并且使用对象类型Double不是一个选项(就像性能相关的原因),通常的做法(据我所知)是创建自己的自定义构造函数:

user> (defrecord Node [^double input-sum ^double last-output])
user.Node

user> (defn make-node [^Double input-sum ^Double last-output]
        (->Node (or input-sum 0) (or last-output 0)))
#'user/make-node

user> (make-node nil 0)
#user.Node{:input-sum 0.0, :last-output 0.0}

user> (make-node 10 nil)
#user.Node{:input-sum 10.0, :last-output 0.0}

user> (make-node 1 2)
#user.Node{:input-sum 1.0, :last-output 2.0}

该方法用于所有情况,您需要一些复杂的逻辑来构建实体。

<强>更新

如果您确实需要两者一个原始值以及区分值与#34;没有值&#34;的方式,您可以使用NaN

user> (defn make-node [^Double input-sum ^Double last-output]
        (->Node (or input-sum Double/NaN) (or last-output Double/NaN)))
#'user/make-node

user> (make-node 1 nil)
#user.Node{:input-sum 1.0, :last-output NaN}

所以,它是值,也是nil的原始类比。

答案 1 :(得分:2)

^double是Java原始double类型的类型提示。试试^Double