clojure java_关于学习Clojure的反馈:与Java流进行比较

clojure java

来自Java背景,我目前正在尝试借助在线资源和指导来学习Clojure编程语言。 几周前,我试图通过寻找与Java流中可用方法等效的方法来将各事物结合在一起。

虽然我设法使事情正常进行,但是编写工作代码和编写惯用代码是两个非常不同的事情。 我很幸运地获得了来自不同来源的大量反馈: Hacker NewsReddit这个博客 。 我要感谢所有以积极方式做出贡献的人,这些人给了我关于Clojure的更多见解。 这篇文章是我收到的最常见反馈的总结。

这是在学习Clojure的焦点series.Other职位包括7 职位:

  1. 解码Clojure代码,让您不知所措
  2. 学习Clojure:应对动态打字
  3. 学习Clojure:arrow和doto宏
  4. 学习Clojure:动态调度
  5. 学习Clojure:依赖类型和基于合同的编程
  6. 学习Clojure:与Java流进行比较
  7. 关于学习Clojure的反馈:与Java流进行比较 (本文)
  8. 学习Clojure:换能器

惯用关键字图

让我们从关于字典访问的简单但似乎非常普遍的用法开始。

为了通过字典中的键检索值,我最初使用了一个命名函数。 然后,我继续使用匿名函数:

(map #(:name %) justice-league)

实际上,匿名函数在Clojure中是样板的。 可以将其替换为简单的关键字访问:

(map :name justice-league)

这将返回相同的结果,但是语法更短。

过滤出零值

为了滤除nil值,我用(not)可用的(nil?)检查取反了:

(filter #(not (nil? %)) [nil
                         {:vehicles [::Bat-Mobile, ::Bat-Plane]}
                         {:vehicles [::Invisible-Plane]}
                         nil
                         nil
                         nil])

产生:

({:vehicles [:sandbox.function/Bat-Mobile :sandbox.function/Bat-Plane]}
 {:vehicles [:sandbox.function/Invisible-Plane]})

但是Clojure提供了一个开箱即用的功能,它的功能完全相同,名为(some?) 。 它的定义如下:

如果x不为nil,则返回true,否则返回false。

(some?)替换初始函数组合非常简单:

(filter some? [nil
               {:vehicles [::Bat-Mobile, ::Bat-Plane]}
               {:vehicles [::Invisible-Plane]}
               nil
               nil
               nil])

总之,最好直接调用一个函数-如果有一个可用的函数,而不是反转另一个函数。

保持在一起

当仅需要保留来自单个键的字典值时,将产生下一个改进。 在上一篇文章中,我依次使用(filter)(map)

(->> [nil
      {:vehicles [::Bat-Mobile, ::Bat-Plane]}
      {:vehicles [::Invisible-Plane]}
      nil
      nil
      nil]
  (filter some?)
  (map :vehicles))

输出如下:

([:sandbox.function/Bat-Mobile :sandbox.function/Bat-Plane]
 [:sandbox.function/Invisible-Plane])

Clojure提供了一个开箱即用的函数,称为(keep) ,其行为类似:

返回(f项目)的非零结果的惰性序列。

- 保持
https://clojuredocs.org/clojure.core/keep

本质上, (keep)仅将映射函数f应用于非nil值。 因此,使用它更新上面的代码很容易:

(keep :vehicles [nil
                 {:vehicles [::Bat-Mobile, ::Bat-Plane]}
                 {:vehicles [::Invisible-Plane]}
                 nil
                 nil
                 nil])

赢取Mapcat!

最后,我们需要展平结果集合。 这是我以前使用的代码:

(->> [nil
      {:vehicles [::Bat-Mobile, ::Bat-Plane]}
      {:vehicles [::Invisible-Plane]}
      nil
      nil
      nil]
  (keep :vehicles)
  (flatten))

返回:

(:sandbox.function/Bat-Mobile
 :sandbox.function/Bat-Plane
 :sandbox.function/Invisible-Plane)

有趣的是,以下内容等同于上述片段:

(->> [nil
      {:vehicles [::Bat-Mobile, ::Bat-Plane]}
      {:vehicles [::Invisible-Plane]}
      nil
      nil
      nil]
  (keep :vehicles)
  (apply concat))

返回一个懒惰的seq,表示所提供coll中元素的串联。

— concat
https://clojuredocs.org/clojure.core/concat

可替代地,Clojure的提供(mapcat)函数,映射函数和应用的组合(concat)

返回将concat应用于将map应用于f和colls的结果。 因此,函数f应该返回一个集合。

— mapcat
https://clojuredocs.org/clojure.core/mapcat

因此,上面的代码可以利用它,如下所示:

(mapcat :vehicles [nil
                   {:vehicles [::Bat-Mobile, ::Bat-Plane]}
                   {:vehicles [::Invisible-Plane]}
                   nil
                   nil
                   nil])
由于应用(concat),nil值会自动过滤掉

最后结果

总而言之,“原始代码”:

(->> justice-league
  (map #(:vehicles %))
  (filter #(not (nil? %)))
  (flatten))

可以用以下简单的单线替换:

(mapcat :vehicles justice-league)

结论

在我以前的文章中,我写道Clojure语法非常有限。 一些评论者不同意这种措词。 实际上,我只能确认:基本构建块很少。

另一方面,有很多可用的现成的宏和函数。 了解它们可以使冗长难读的代码与惯用的代码有所不同。

再次感谢所有给我反馈的人。 我希望继续学习Clojure,如有需要,请不要犹豫,引导我正确的方向!

翻译自: https://blog.frankel.ch/learning-clojure/6/

clojure java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值