Scala提供了类Option[T]
,Some[T] extends Option[T]
和None extends Option[Nothing]
的层次结构,我发现这些类包含了可以返回null
的Java方法调用,其中包括:
val result = Option(someJavaMethodThatReturnsNull())
result
的作用类似于零个或一个项目的序列,具体取决于Java方法是返回对象还是null
。 Option
有map
,filter
等方法,您可以像序列中的那些一样使用并返回新序列(Some
),如果原始序列是如果原件为Some[T]
,则为None
或None
。
Clojure函数seq
的行为似乎相似:如果x为非空,则(seq x)
将是一个项的序列;如果x为null,则nil
将是(map ...)
。然后,可以将此值传递到(filter ...)
,Option
等,就像Scala {{1}}方法一样。
我错过了什么吗?这种模式有意义吗?这是“尤里卡!”那些对经验丰富的Clojure程序员来说很明显的时刻?
答案 0 :(得分:2)
你总是可以使用maybe monad,它接近scala Option(和haskell Maybe),当然没有静态类型安全。
还有the family of ? threading functions(。?。是java互操作的更好选择)
答案 1 :(得分:2)
您当然可以使用Clojure序列来表示零个,一个或多个返回值。
如果您的函数实际上需要返回一个集合,那么这是一种明智的方法,非常惯用。
但是我不建议使用序列来模拟选项类型。这可能会使您的API用户感到困惑。在Clojure中,正常和惯用的方法是,如果值不可用则返回nil,如果值是直接返回值。
比较
(if-let [a (function-that-returns-nil-or-result)]
(do-something-with a))
如果您使用序列来模拟选项类型,那么您将需要:
(if-let [a (function-that-returns-a-possibly-empty-sequence)]
(do-something-with (first a)))
我绝对更喜欢第一个选项....为什么我们需要或希望API用户使用first
从序列中解压缩结果?
一般来说,nil在Clojure中效果很好(比其他语言好得多)因为:
答案 2 :(得分:1)
没有。如果集合非空,seq
将返回集合上的抽象顺序视图。否则nil
。所以它与你想要的完全无关。但是,如果测试,您可以使用nil
。例如
(when-let [thing (.someMethodThatReturnsSomethingOrNil other-thing)]
(run-only-when thing is-not-nil-or-false))
这是你想要的吗?
编辑:注意错误。
答案 3 :(得分:0)
(seq x)
为nil
,则 x
将返回nil
或空集合。但是,map
,filter
等将接受nil
作为其集合参数(即,它们不会中断)并返回空序列。这可能会给出Scala的Option
语句所期望的结果。
以下各项将返回一个空序列:
(map (fn [x] x) (seq nil))
(map (fn [x] x) (seq `()))
(filter even? (seq nil))
(filter even? (seq `()))