If statement 如果条件为真,如何运行多个表达式?

If statement 如果条件为真,如何运行多个表达式?,if-statement,scheme,If Statement,Scheme,我是Scheme的新手,正在尝试让if语句在其条件为true时执行多个操作。我试过这样的方法: (if (char=? (string-ref str loc) #\a) ((+ count 1) (+ reference 1)) ~else action, etc.~ 它抱怨我的行为,说 应用:不是一个程序 如果我删除括号,则true条件的操作为: (+ count 1) (+ reference 1) 它抱怨 if:语法错误 根本无法运行。我遗漏了什么?您

我是Scheme的新手,正在尝试让if语句在其条件为true时执行多个操作。我试过这样的方法:

(if (char=? (string-ref str loc) #\a)
        ((+ count 1) (+ reference 1))
        ~else action, etc.~
它抱怨我的行为,说

应用:不是一个程序

如果我删除括号,则true条件的操作为:

(+ count 1) (+ reference 1)
它抱怨

if:语法错误


根本无法运行。我遗漏了什么?

您可以使用
begin
将一组要逐个执行的表达式分组

(if (char=? (string-ref str loc) #\a)
        (begin (+ count 1) (+ reference 1))
        ~else action, etc.~

begin
只返回最后一个表达式的值,即
(+reference 1)
,因此不使用
(+count 1)
的值。

代码有两个问题。第一,一个
if
表单在结果和替换中不能有多个表达式。两种可能的解决方案-您可以使用
begin
(不只是几个括号,这是用于过程应用的)来包围多个表达式:

(if (char=? (string-ref str loc) #\a)
    ; needs an explicit `begin` for more than one expression
    (begin
      (+ count 1)
      (+ reference 1))
    ; needs an explicit `begin` for more than one expression
    (begin
      ~else action, etc~))
。。。或者使用
cond
,这是一个更好的选择,因为它已经包含一个隐式的
begin

(cond ((char=? (string-ref str loc) #\a)
       ; already includes an implicit `begin`
       (+ count 1)
       (+ reference 1))
      (else
       ; already includes an implicit `begin`
        ~else action, etc~))
第二个问题更加微妙和严重,后续部分中的两个表达式可能都没有达到您预期的效果。这个:
(+count 1)
什么也不做,递增的值丢失了,因为在递增后没有使用它。与另一个相同:
(+reference 1)
,但至少在这里,该值是作为条件表达式的结果返回的。您应该将两个递增的值一起传递给一个过程(可能是递归的一部分):

或者直接在变量中更新增量的结果,尽管这不是在Scheme中编写解决方案的惯用方法(它看起来像C、Java等中的解决方案):


如果您试图在
If
的一个手臂上执行多个副作用的操作,那么您需要将它们放入
开始
,如下所示:

(if (char=? (string-ref str loc) #\a)
    (begin (set! count (+ count 1))
           (set! reference (+ reference 1)))
    ~else action, etc.~
(if (char=? (string-ref str loc) #\a)
    (cons (+ count 1) (+ reference 1)))
    ~else expression~
(if (char=? (string-ref str loc) #\a)
    (values (+ count 1) (+ reference 1)))
    ~else expression~
(define count&ref
  (λ (str ch)
    (let loop ([loc 0] [count 0] [reference 0])
      ; whatever other stuff you're doing
      (if (char=? (string-ref str loc) ch)
          (values (+ count 1) (+ reference 1)))
          ~else expression~ )))

(let-values ([(new-count new-ref) (count&ref "some stuff" #\u)])
  ;in here, new-count and new-ref are bound to whatever count&ref returned
  )
(let loop ([loc 0] [count 0] [reference 0])
  ; whatever other stuff you're doing
  (if (char=? (string-ref str loc) #\a)
      (loop (+ loc 1) (+ count 1) (+ reference 1))
      ~else expression~ ))
如果您希望同时返回两个值,而不是引起变量的更改,则需要将表达式组合到单个对象中,如下所示:

(if (char=? (string-ref str loc) #\a)
    (begin (set! count (+ count 1))
           (set! reference (+ reference 1)))
    ~else action, etc.~
(if (char=? (string-ref str loc) #\a)
    (cons (+ count 1) (+ reference 1)))
    ~else expression~
(if (char=? (string-ref str loc) #\a)
    (values (+ count 1) (+ reference 1)))
    ~else expression~
(define count&ref
  (λ (str ch)
    (let loop ([loc 0] [count 0] [reference 0])
      ; whatever other stuff you're doing
      (if (char=? (string-ref str loc) ch)
          (values (+ count 1) (+ reference 1)))
          ~else expression~ )))

(let-values ([(new-count new-ref) (count&ref "some stuff" #\u)])
  ;in here, new-count and new-ref are bound to whatever count&ref returned
  )
(let loop ([loc 0] [count 0] [reference 0])
  ; whatever other stuff you're doing
  (if (char=? (string-ref str loc) #\a)
      (loop (+ loc 1) (+ count 1) (+ reference 1))
      ~else expression~ ))
在这种情况下,要提取计数和参考,您需要将
car
cdr
应用于
if
的结果,或者您可以实际返回多个值,如下所示:

(if (char=? (string-ref str loc) #\a)
    (begin (set! count (+ count 1))
           (set! reference (+ reference 1)))
    ~else action, etc.~
(if (char=? (string-ref str loc) #\a)
    (cons (+ count 1) (+ reference 1)))
    ~else expression~
(if (char=? (string-ref str loc) #\a)
    (values (+ count 1) (+ reference 1)))
    ~else expression~
(define count&ref
  (λ (str ch)
    (let loop ([loc 0] [count 0] [reference 0])
      ; whatever other stuff you're doing
      (if (char=? (string-ref str loc) ch)
          (values (+ count 1) (+ reference 1)))
          ~else expression~ )))

(let-values ([(new-count new-ref) (count&ref "some stuff" #\u)])
  ;in here, new-count and new-ref are bound to whatever count&ref returned
  )
(let loop ([loc 0] [count 0] [reference 0])
  ; whatever other stuff you're doing
  (if (char=? (string-ref str loc) #\a)
      (loop (+ loc 1) (+ count 1) (+ reference 1))
      ~else expression~ ))
在这种情况下,要提取计数和引用,您需要以某种方式将多个值绑定到调用
if
的代码中的变量。一种方法是使用
让值
,可能是这样的:

(if (char=? (string-ref str loc) #\a)
    (begin (set! count (+ count 1))
           (set! reference (+ reference 1)))
    ~else action, etc.~
(if (char=? (string-ref str loc) #\a)
    (cons (+ count 1) (+ reference 1)))
    ~else expression~
(if (char=? (string-ref str loc) #\a)
    (values (+ count 1) (+ reference 1)))
    ~else expression~
(define count&ref
  (λ (str ch)
    (let loop ([loc 0] [count 0] [reference 0])
      ; whatever other stuff you're doing
      (if (char=? (string-ref str loc) ch)
          (values (+ count 1) (+ reference 1)))
          ~else expression~ )))

(let-values ([(new-count new-ref) (count&ref "some stuff" #\u)])
  ;in here, new-count and new-ref are bound to whatever count&ref returned
  )
(let loop ([loc 0] [count 0] [reference 0])
  ; whatever other stuff you're doing
  (if (char=? (string-ref str loc) #\a)
      (loop (+ loc 1) (+ count 1) (+ reference 1))
      ~else expression~ ))
另一方面,如果
count
reference
是循环中跟踪的变量,最简单的方法可能是在
if
中调用循环的下一次迭代,如下所示:

(if (char=? (string-ref str loc) #\a)
    (begin (set! count (+ count 1))
           (set! reference (+ reference 1)))
    ~else action, etc.~
(if (char=? (string-ref str loc) #\a)
    (cons (+ count 1) (+ reference 1)))
    ~else expression~
(if (char=? (string-ref str loc) #\a)
    (values (+ count 1) (+ reference 1)))
    ~else expression~
(define count&ref
  (λ (str ch)
    (let loop ([loc 0] [count 0] [reference 0])
      ; whatever other stuff you're doing
      (if (char=? (string-ref str loc) ch)
          (values (+ count 1) (+ reference 1)))
          ~else expression~ )))

(let-values ([(new-count new-ref) (count&ref "some stuff" #\u)])
  ;in here, new-count and new-ref are bound to whatever count&ref returned
  )
(let loop ([loc 0] [count 0] [reference 0])
  ; whatever other stuff you're doing
  (if (char=? (string-ref str loc) #\a)
      (loop (+ loc 1) (+ count 1) (+ reference 1))
      ~else expression~ ))