首页 文章

如何根据Scheme / Racket中的条件实际定义很多东西?

提问于
浏览
6

我在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 更改 n 次定义的内容量 . 有没有更好的方法来做到这一点,如果是这样的话:怎么样?

2 回答

  • 4

    如果"a lot"非常大,您可能想要使用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
    
  • 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")))
    

相关问题