【Janet】绑定(def和var)
使用 def 将值绑定到符号。使用未绑定的符号会抛出异常。
(def a 100)
(def b (+ 1 a))
(def c (+ b b))
(def d (- c 100))
def 创建的绑定具有词法作用域。此外 def 创建的绑定是不可变的;它们在定义之后不能修改。对于可变的绑定,像其他语言中的变量,使用 var 关键字。赋值表达式 set 可以用来修改 var 变量的值。
(def a 100)
(var myvar 1)
(print myvar)
(set myvar 10)
(print myvar)
在全局作用域,可以在 def 和 var 中使用 :private 选项防止绑定被导出到引入该模块的代码中。你也可以给 def 或 var 传递一个字符串来添加文档。
(def mydef :private "This will have private scope. My doc here." 123)
(var myvar "docstring here" 321)
作用域
作用域就是绑定生效的地方。如果在绑定的作用域外引用它,编译器就会报错。作用域可以有效组织绑定和扩展你的程序。有两种方法在 Janet 中创建作用域。
第一种方式是使用 do 表达式。 do 执行作用域内的多个语句并以最后一个语句做为结果。表达式内创建的绑定不会逃出它的作用域。
(def a :outera)(do(def a 1)(def b 2)(def c 3)(+ a b c)) # -> 6a # -> :outera
b # -> compile error: "unknown symbol \"b\""
c # -> compile error: "unknown symbol \"c\""
尝试在 do 语句结束后访问 do 语句内的绑定都会失败。在 do 表达式内定义的 a 不会覆盖全局作用域内已定义的 a。
第二种创建作用域的方式是创建闭包。 fn 表达式也会引入一个作用域,和 do 表达式一样。
还有一个内置的宏 let 可以一次性实现多个绑定,并引入一个作用域。 let 是 def 和 do 组合的包裹,它是创建绑定最“函数式”的方式。
(let [a 1b 2c 3](+ a b c)) # -> 6
上面的代码等价于使用 do 和 def 的例子。这是大多数情况下的首选方式,但是,使用 do 和多个 def 也是可以的。
