Clojure seq 作为 Scala Option 的替代品[T]
Scala 提供了类 Option[T]
、Some[T] extends Option[T]
和 None extends Option[Nothing]
的层次结构,我发现对于包装可以返回 null 的 Java 方法调用很有用,除此之外:
val result = Option(someJavaMethodThatReturnsNull())
结果的行为就像一个由零个或一个项目组成的序列,具体取决于 Java 方法是否返回一个对象或null
。 Option
具有诸如 map
、filter
等方法,您可以像在序列上使用这些方法一样使用这些方法,也可以返回一个新序列(>Some
),如果原始是 Some[T]
,或者 None
如果原始是 None
。
Clojure 函数 seq
的行为类似:如果 x 不为 null 或 nil
,(seq x)
将是一个包含一项的序列如果 x 为空。然后可以将该值传递给 (map ...)
、(filter ...)
等,就像 Scala Option
一样方法。
我错过了什么吗?这种模式有意义吗?这是“尤里卡”吗?对于经验丰富的 Clojure 程序员来说,这是显而易见的时刻吗?
Scala offers a hierarchy of classes Option[T]
, Some[T] extends Option[T]
, and None extends Option[Nothing]
that I have found useful for wrapping Java method calls that can return null
, among other things:
val result = Option(someJavaMethodThatReturnsNull())
result
acts like a sequence of zero or one items, depending on whether the Java method returned an object or null
. Option
has methods like map
, filter
, etc. that you can use just like those on a sequence and either return a new sequence (Some
), if the original was Some[T]
, or None
if the original was None
.
It appears that the Clojure function seq
behaves similarly: (seq x)
will be a sequence of one item if x is non-null or nil
if x is null. This value can then be passed to (map ...)
, (filter ...)
, etc., just like the Scala Option
methods.
Am I missing something? Does this pattern make sense? Is this a "Eureka!" moment that is obvious to experienced Clojure programmers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你总是可以使用 也许 monad< /a>,它接近 scala Option(也许还有 haskell),当然没有静态类型安全。
还有家族?线程函数(.?.是java互操作的更好选择)
You always could use the maybe monad, which is close to scala Option (and haskell Maybe) without static type safety of course.
Also there is the family of ? threading functions (.?. is the better choice for java interop)
您当然可以使用 Clojure 序列来表示零个、一个或多个返回值。
如果您的函数实际上希望返回一个集合,那么这是一种明智的方法并且非常惯用。
不过,我不建议使用序列来模拟选项类型。这可能会让 API 的用户感到困惑。在 Clojure 中,正常且惯用的方法是如果值不可用则返回 nil,如果可用则直接返回该值。
比较:
如果您使用序列来模拟选项类型,您将需要什么:
我绝对更喜欢第一个选项...为什么我们需要或希望 API 用户使用
first< 从序列中解压结果/代码>?
一般来说,nil 在 Clojure 中工作得很好(比其他语言好得多),因为:
You can certainly use a Clojure sequence to represent zero, one or more return values.
It is a sensible approach and very idiomatic if your function is actually expected to return a collection.
However I would not recommend using a sequence to emulate an option type. This is likely to confuse users of your API. In Clojure, the normal and idiomatic way to is just to return nil if a value is not available, and return the value directly if it is.
Compare:
With what you would need if you used a sequence to emulate an option type:
I definitely prefer the first option.... why do we need or want the API user to unpack the result from the sequence with
first
?In general, nil works pretty well in Clojure (much better than in other languages) because:
不会。如果集合非空,
seq
将返回集合的抽象顺序视图。否则nil
。所以这和你想要的完全无关。但是,您可以在 if 测试中使用nil
。例如。这就是你的意图吗?
编辑:谨防虚假信息。
No.
seq
will either return an abstract, sequential view on a collection in case the collection is non-empty.nil
otherwise. So it is completely unrelated to what you want. However you can usenil
in if tests. eg.Is that what you intend?
Edit: Beware the false.
如果
x
为nil
或空集合,(seq x)
将返回nil
。然而,map、filter等将接受nil作为它们的集合参数(即它们不会中断)并返回一个空序列。这可能会给出您期望从 Scala 的Option
语句得到的结果。以下将分别返回一个空序列:
(seq x)
will returnnil
ifx
isnil
or an empty collection. However,map
,filter
etc. will acceptnil
as their collection argument (i.e., they won't break) and return an empty sequence. This may give the result that you expect from Scala'sOption
statement.The following will each return an empty sequence: