美文网首页
4. 局部变量 (newLISP 代码模式 v.10.6.2)

4. 局部变量 (newLISP 代码模式 v.10.6.2)

作者: newlisp | 来源:发表于2018-02-09 11:14 被阅读0次

    循环函数中的局部变量

    所有的循环函数都使用局部变量,比如doargs, dolist, dostring, dotimes, dotree和 for . 在循环执行期间,每次循环都给变量赋予不同的值. 但在离开循环函数后,变量将恢复其原来的值 。let,define, 和lambda 是另一种声明局部变量的方法:

    用let,letn,local 和letex 声明局部变量

    let是一种常见的在代码块中申明局部变量的方法.

        (define (sum-sq a b)

            (let ((x (* a a)) (y (* b b)))

                (+ x y)))

        (sum-sq 3 4) → 25

        ; alternative syntax

        (define (sum-sq a b)

            (let (x (* a a) y (* b b))

                (+ x y)))

    变量x和y先被初始化,然后执行表达式(+ x y). let 方法其实就是下面语句的优化版本也就是一个语法糖:

    ((lambda (sym1 [sym2 ...]) exp-body ) exp-init1 [ exp-init2 ...])

    当初始化多个参数时, 一个嵌套的 let, letn 就能够使之前初始化过的参数可以被应用到他之后参数的初始化中:

        (letn ((x 1) (y (+ x 1)))

            (list x y))              → (1 2)

    local的工作方式相同,只不过把变量初始化成 nil.

        (local (a b c)

          ...          ; expressions using the locale variables a b c

        )

    letex的工作原理和let类似,不同的是letex将变量在函数体内展开到指定的值。

        ; assign to local variable and expand in body

        (letex ( (x 1) (y '(a b c)) (z "hello") ) '(x y z))

        → (1 (a b c) "hello")

        ; as in let, parentheses around the initializers can be omitted

        (letex (x 1 y 2 z 3) '(x y z))    → (1 2 3)

    当离开函数let、letn、local、letex的函数作用域后,声明的局部变量将恢复旧值。

    未使用的参数做局部变量

    在 newLISP 中, 用户定义函数中的所有参数都是可选的.未使用的参数被赋值为nil,只局限在本函数的局部作用域或动态作用域内。定义比函数需求参数更多的参数用作函数的局部变量,是定义局部变量一个比较方便的方法:

        (define (sum-sq a b , x y)

            (set 'x (* a a))

            (set 'y (* b b))

            (+ x y))

    逗号不是一种特殊的语法,它只在视觉上将函数参数和局部变量区分开. (从技术上讲逗号, 和 x , y 一样, 也是一个局部变量,被初始化成nil.)

    参数默认值

    定义函数的时候能够给参数指定默认值:

        (define (foo (a 1) (b 2))

            (list a b))

            (foo)      →  (1 2)

            (foo 3)    →  (3 2)

            (foo 3 4)  →  (3 4)

    用 args 替代 local

    使用args函数时,不需要为其定义任何参数符号,args返回一个已经传递的参数列表,但列表不包含已经声明过的参数:

        (define (foo)

            (args))

        (foo 1 2 3)  → (1 2 3)

        (define (foo a b)

            (args))

        (foo 1 2 3 4 5)  → (3 4 5)

    第二个例子中 args 返回的参数值列表,排除了赋值给 a 和 b 的参数值.

    通过索引可以访问 (args) 列表:

        (define (foo)

              (+ (args 0) (args 1)))

        (foo 3 4)  → 7

    使用args和local来命名参数

        (define-macro (foo)

            (local (len width height)

                (bind (args) true)

                (println "len:" len " width:" width " height:" height)

        ))

        > (foo (width 20) (height 30) (len 10))

        len:10 width:20 height:30

        > (foo (width (+ 15 5)) (height 30) (len 10))

        len:10 width:20 height:30

        > (foo (width (+ 15 5)) (height (* width 2)) (len 10))

        len:10 width:20 height:40

    local会屏蔽上层作用域对局部作用域中len、widht、height变量值的影响,保持变量在本作用域中的值.

    相关文章

      网友评论

          本文标题:4. 局部变量 (newLISP 代码模式 v.10.6.2)

          本文链接:https://www.haomeiwen.com/subject/oqjftftx.html