可为空的双类型提示

Nullable Double Type-Hint

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

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

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

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

不幸的是,创建上述节点会产生 NPE;显然是因为它试图将 nil 转换为 double:

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

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

我正在努力养成尽我所能进行类型提示的习惯。有没有办法在 last-output 上提供类型提示,同时指出 nil 是一个可接受的值?

^double 是 Java 原始双精度类型的类型提示。试试 ^Double.

如果你真的需要使用原始类型进行类型提示,并且使用对象类型 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}

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

更新

如果你真的需要 原始值和区分值与 "no value" 的方法,你可以使用 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的原始类比。