Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure seq替代Scala期权[T]_Scala_Clojure_Option_Seq - Fatal编程技术网

Clojure seq替代Scala期权[T]

Clojure seq替代Scala期权[T],scala,clojure,option,seq,Scala,Clojure,Option,Seq,Scala提供了一个类的层次结构,Option[T],Some[T]扩展Option[T],以及None扩展Option[Nothing],我发现这些类对于包装可以返回null的Java方法调用非常有用 val result = Option(someJavaMethodThatReturnsNull()) result的行为类似于零项序列或一项序列,这取决于Java方法是返回对象还是null选项具有类似于映射、过滤器等的方法。您可以像序列上的方法一样使用这些方法,如果原始序列是Some[T]

Scala提供了一个类的层次结构,
Option[T]
Some[T]扩展Option[T]
,以及
None扩展Option[Nothing]
,我发现这些类对于包装可以返回
null
的Java方法调用非常有用

val result = Option(someJavaMethodThatReturnsNull())
result
的行为类似于零项序列或一项序列,这取决于Java方法是返回对象还是
null
选项
具有类似于
映射
过滤器
等的方法。您可以像序列上的方法一样使用这些方法,如果原始序列是
Some[T]
,则返回新序列(
Some
),或者如果原始序列是
None

Clojure函数
seq
的行为似乎类似:
(seq x)
如果x为非null,则为一项序列;如果x为null,则为
nil
。然后可以将该值传递给
(map…
(filter…
)等,就像Scala
选项
方法一样


我错过什么了吗?这种模式有意义吗?对于有经验的Clojure程序员来说,这是一个显而易见的“妙不可言”时刻吗?

否。
seq
将在集合非空的情况下返回集合的抽象顺序视图<代码>无否则。所以这与你想要的完全无关。但是,您可以在if测试中使用
nil
。例如

(when-let [thing (.someMethodThatReturnsSomethingOrNil other-thing)]
  (run-only-when thing is-not-nil-or-false))
这就是你的意图吗

编辑:注意错误。

(seq x)
如果
x
nil
或空集合,则将返回
nil
。但是,
map
filter
等将接受
nil
作为其集合参数(即,它们不会中断),并返回空序列。这可能会给出Scala的
选项
语句所期望的结果

以下各项将返回一个空序列:

(映射(fn[x]x)(顺序为零))
(图(fn[x]x)(seq`())
(过滤器偶数?(顺序为零)
(筛选偶数?(seq`())
您始终可以使用,这接近scala选项(可能还有haskell),当然没有静态类型安全性


还有(.?.是java互操作的更好选择)

您当然可以使用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用户先用
解压序列中的结果

一般来说,nil在Clojure中工作得非常好(比其他语言好得多),因为:

  • 所有库函数都将nil解释为空序列,因此您不太可能遇到NullPointerException
  • nil也被认为是“错误的”,因此可以方便地用于布尔运算

旁注:这种集合和选项(以及更多)的共享结构通过and类在Haskell中捕获。但是大多数(全部?)在序列上操作的Clojure函数接受
nil
(map nil)
,等等。在函数的“行尾”处,您可能需要测试nil,但如果调用,您可以只传递上一个函数返回的内容。但是
seq
对您没有帮助,因为任意对象是不可排序的<代码>地图
和朋友的工作级别与
选项
不同。我发现编写一个函数
nil
-安全,然后只使用
->
comp
更容易。YMMV。