在尝试保持功能风格时,我很难理解何时应该更喜欢:
(-> [1 2 3] reverse last)
超过:
(last (reverse [1 2 3]))
当我在一个项目中遇到这两种风格时,我发现它打破了我的流程,因为我必须在考虑函数组合和考虑中间值状态之间切换。
我应该在什么时候使用哪个?
我大多避免使用->
单参数函数;当您拥有多参数函数时,它会更有用,因为它可以让您将每个函数保持在其“额外参数”旁边,而不会被焦点对象遮挡。
而且,你不必选择一个或另一个极端:我最喜欢的事情之一->
是它允许你以任何顺序编写函数,你可以利用这种自由以任何方式编写代码你认为是最具可读性的。例如,也许您想强调您正在获取集合的最后一个,并且在上下文中它首先被反转的事实是无趣的:
(last (-> [1 2 3] (reverse)))
或者也许倒车很重要,最后很无聊:
(-> (reverse [1 2 3]) (last))
顺便说一句,请注意我在这里写了(last)
和(reverse)
,而不是仅仅last
,reverse
即使->
宏隐式地为你插入括号,如果你把它们排除在外。这是故意的:虽然它不是一种非常流行的风格,但我认为在给定的形式中始终使用括号是个好主意->
。有几个原因:
(-> (blah) (fn [x] (+ 1 (* x 5))))
奇怪地扩展时你不会感到惊讶,因为你习惯于认为它->
采用一种形式而不是一种功能。->
它在具有一些一元函数和其他多参数函数的多行中看起来更规则。例如:
(-> attrs
(update :sessions inc)
frobnicate
save-to-disk
(get :uuid))
把这两个东西放在中间是不是很恶心,看起来和其他东西都不一样?
我见过的唯一一个省略()
s 的论点是它节省了两个打字字符,这根本不是一个论点。
我的简短经验法则是“哪个更接近于更具陈述性的英语句子”。如果您将它们粗略地翻译成描述性的句子,我倾向于选择更准确地说明正在产生的事物的句子,而不是描述创建结果的过程的选项。有些人会想选择另一种方式。这些东西总是口味问题。
例如:
(last (reverse [1 2 3]))
几乎是“最后倒车 1 2 3”(-> [1 2 3] reverse last)
有点像“从 1 2 3,反向,最后”我发现第一个更具声明性,在这种情况下会选择它,其他人会选择不同的。
由于它们在功能上是相同的,所以要考虑的主要问题是哪个使代码更具可读性和可维护性?
这基本上是一个判断电话。
->
在以下情况下通常很有用:
(f (g x))
style 在其他情况下很有用:
->
) 或最后一个 (with ->>
) 参数我同意那些已经回答的人,但我要补充一点,如果你和很多使用 C 的人一起工作,后一种格式可能对他们来说更易读,而如果你和很多 C# 大师一起工作,他们会更熟悉以前的格式与扩展方法。
其他答案没有错,但我只想补充一点,->
对我来说真正有意义的时候是你想强调应用了一系列操作。从左到右阅读意味着您自然会看到计算函数的顺序,一旦您超过 2 或 3 层嵌套,这真的很有帮助。使用长手形式,您有时必须在脑海中解析括号,深入到最低级别,然后返回以了解正在发生的事情。