是否可以重写下面的表达式,以便(foo)
只出现一次?虽然它并不可怕,但是这些反复调用(foo)
会使代码难以阅读。
(cond
(a
(x)
(foo))
(b
(y)
(foo))
(else
(z)
(bar)))
答案 0 :(得分:2)
我不确定这是技术问题"回答你的问题,"但我不同意,反复拨打foo
会使代码难以阅读"。实际上,我会声称他们让更容易阅读。具体来说,在重构版本中,您有条件分支和尾随代码(对foo的调用)。这意味着作为一个读者,我必须牢记在阅读有条件的事实,即后来会发生更多这样的事实。更重要的是,查看重构代码中的foo
,我们无法确定在此之前执行的代码是什么;原来没有这个问题。
当重复大块代码时,会使代码难以阅读且易碎。当重复单个调用时,就像这里一样,它通常使代码更容易阅读,特别是如果函数具有有意义的名称。
在这里,让我为你重温:
(cond
[a (x)
(foo)]
[b (y)
(foo)]
[else (z)
(bar)])
答案 1 :(得分:2)
如果(foo)
你的意思是复杂的话,我建议:
(let ()
(define (f) (foo))
(cond
(a (x) (f))
(b (y) (f))
(else (z) (f))))
或
(let ((f (lambda () (foo))))
(cond
(a (x) (f))
(b (y) (f))
(else (z) (f))))
答案 2 :(得分:1)
不一定更具可读性:)但这可行。
(cond ((or a b) ((cond (a (x)) (b (y))) (foo)) (else (z) (bar)))
答案 3 :(得分:1)
是,
(cond
((cond
(a
(x)
#t)
(b
(y)
#t)
(else
(z)
#f)) (foo))
(else (bar)))
如果a
或b
是复杂的表达式,则不会引入其他测试。
答案 4 :(得分:1)
又一个选择:
(let ((myfoo (lambda (x) (x) (foo))))
(cond (a (myfoo x))
(b (myfoo y))
(else (z) (bar))))