let vs def in clojure
我想在clojure程序中创建Java
1 2 | ; gives me: count not supported on this type: Symbol (let s (new Scanner"a b c")) |
但这会让我创建一个如下的全局实例:
1 | (def s (new Scanner"a b c")) |
我的印象是唯一的区别是范围,但显然不是。
问题是您对
让我们这样工作:
1 | (let [identifier (expr)]) |
因此,您的示例应如下所示:
1 2 | (let [s (Scanner."a b c")] (exprs)) |
您只能在let(开始和结束括号)的范围内使用let进行的词法绑定。让我们只创建一组词法绑定。我使用def进行全局绑定,并仅在let的范围内绑定我想要的东西,因为它可以使事物保持整洁。它们都有用途。
注意:(类)与(新类)相同,只是语法糖。
LET不是"在当前范围内建立词法绑定",而是"使用以下绑定来建立新的词法范围"。
1 2 3 4 | (let [s (foo whatever)] ;; s is bound here ) ;; but not here |
1 2 | (def s (foo whatever)) ;; s is bound here |
简化:def用于全局常量,let用于局部变量。
正确的语法:
1 | (let [s (Scanner."a b c")] ...) |
即使它们的含义相关,它们的语法也不同。
let获取绑定列表(名称/值对),后跟要在绑定上下文中求值的表达式。
def仅接受一个绑定而不是列表,并将其添加到全局上下文中。
您可以将
1 2 3 | (let [a 3 b 7] (* a b)) ; 21 ; vs. ((fn [a b] (* a b)) 3 7) ; 21 |
因此,您可以使用简单的宏和
1 2 3 4 5 6 | (defmacro fnlet [bindings & body] ((fn [pairs] `((fn [~@(map first pairs)] ~@body) ~@(map last pairs))) (partition 2 bindings))) (fnlet [a 3 b 7] (* a b)) ; 21 |