racket提供三个函数执行本地绑定<code>let</code>,<code>let*</code>,<code>letrec</code>.
4.6.1平行绑定:let
let绑定表达式的结果到标识符,在let方法体中试用。
(let ([id expr] ...) body ...+)
id的绑定是平行的,id的标识符不能相同。
id的表达式无法使用它自己本身的绑定这个事实对包装原值的引用是很有用的。
平行特性偶尔对交换值绑定也是很有用的。
(let ([me "Tarzen"]
[you "Jane"]
(let ([me you]
[you me])
(list me you)))
平行特性并不意味着它们是并发执行的,绑定发生在所有表达式都执行完毕,但是表达式的执行还是顺序的。
4.6.2顺序绑定
<code>let*</code>和<code>let</code>类似。
(let* ([id expr] ...) body ...+)
不同的是每个id都可以在后面的表达式里使用。id不一定要不同,最近定义的那个绑定将被使用。
换种说法,let*其实是一种内嵌let形式的等价。
(let ([name (list "Borroughs")])
(let ([name (cons "Rice" name)])
(let ([name (cons "Edgar" name)])
name)))
4.6.3递归绑定:letrec
(letrec ([id expr] ...) body ...+)
<code>let</code>绑定只在方法体里面使用,<code>let*</code>在之后的绑定表达式里可用,<code>letrec</code>在任何表达式都可用,即使在定义之前。引文它们是递归的。
letrec一般是用于lambda表达式,但是它能使用一般表达式。
4.6.4 命名let
命名let是一个迭代和递归的形式。语法和let相同,但是直接跟标识符触发不同的语法解析。
(let proc-id ([arg-id init-expr] ...)
body ...+)
它等价于
(letrec ([proc-id (lambda (arg-id ...)
body ...+)])
(proc-id init-expr ...))
它的含义是,命名let绑定到一个函数到标识符。这个函数只在函数体里面可见,并且使用初始值作为参数执行该函数。
4.6.5多值绑定:let-values,let*-values,letrec-values
<code>let-values</code>,<code>let*-values</code>,<code>letrec-values</code>可以进行本地的多值绑定。
(let-values ([(id ...) expr] ...)
body ...+)
(let*-values ([(id ...) expr] ...)
body ...+)
(letrec-values([(id ...) expr] ...)
body ...+)
expr必须产生和表达式一样多的值。绑定规则和没有form的<code>let</code>,<code>let*</code>,<code>letrec</code>一样。
网友评论