我在Racket工作,但据我所知,这是一般的方案;你不能做这样的事情,因为我们试图在表达式上下文中定义一些东西:
(if condition
(define x "do a backflip")
(define x "do a barrel roll"))
现在对于这个特例,我可以做一些这样的事情:
(define x
(if condition
"do a backflip"
"do a barrel roll"))
但如果你有很多不同的东西要定义,这真的很糟糕,因为而不是
(if condition
(begin (define x "do a backflip")
(define y "awesome")
(define z "shoot me"))
(begin (define x "do a barrel roll")
(define y "nice")
(define z "give me sweet release")))
我们得到了
(define x
(if condition
"do a backflip"
"do a barrel roll"))
(define y
(if condition
"awesome"
"nice"))
(define z
(if condition
"shoot me"
"give me sweet release"))
这不是DRY,我们不断重复condition
的测试。结果是,如果我们不想测试condition
我们要检查other-condition
,我们必须对n
次{}进行更改。有没有更好的方法来做到这一点,如果是这样的话:怎么样?
答案 0 :(得分:5)
使用define-values
:
(define-values (x y z) (if condition
(values "do a backflip" "awesome" "shoot me")
(values "do a barrel roll" "nice" "give me sweet release")))
答案 1 :(得分:4)
如果"很多"非常大,您可能想要使用Racket的units
。
首先使用您要定义的所有变量定义签名:
(define-signature acro^ (x y z))
然后定义包含不同定义集的单位:
(define-unit flippy@
(import) (export acro^)
(define x "do a backflip")
(define y "awesome")
(define z "shoot me"))
(define-unit rolly@
(import) (export acro^)
(define x "do a barrel roll")
(define y "nice")
(define z "give me sweet release"))
您可以动态选择调用的单位并绑定到签名中的名称:
(define-values/invoke-unit
(if .... flippy@ rolly@)
(import) (export acro^))
x
;; => either "do a backflip" or "do a barrel roll", depending on condition