最近我在chrome控制台遇到了这个奇怪的事情.在这里,我故意为a分配一个未定义的东西,以便抛出错误.
let a = werwr // Uncaught ReferenceError: werwr is not defined
Run Code Online (Sandbox Code Playgroud)
然后,当我尝试为a分配合法的东西时,发生了这种情况:
let a = "legit string" // Uncaught SyntaxError: Identifier 'a' has already been declared
Run Code Online (Sandbox Code Playgroud)
所以我不能使用"let",因为已经声明了.所以我试图将其他东西重新分配给"已经宣布为"
a = "legit string" // Uncaught ReferenceError: a is not defined
Run Code Online (Sandbox Code Playgroud)
所以我似乎无法将其他内容重新分配给a,但同时,a已经声明,所以我不能再使用let了.
我理解声明和赋值变量之间的区别.但是在这里似乎不能再做了.这是否与控制台中"let"的范围有关?因为同样的事情完全适用于"var"
var a = werwr
// Uncaught ReferenceError: werwr is not defined
a = ”legit string“
// ”legit string“
var a = "legit string"
// Uncaught SyntaxError: Identifier 'a' has already been declared
Run Code Online (Sandbox Code Playgroud)
跟进
"手动"提升let语句与隐式大小写之间似乎存在一些差异.
throw new Error
let example …Run Code Online (Sandbox Code Playgroud) 我正在尝试嵌套一些let语句,但我收到的语法错误对我来说没有意义.我是Haskell编程的新手,所以我确定这是我不理解的东西(可能与间距有关).我知道let和in必须在同一列中.
为什么:
aaa = let y = 1+2
z = 4+6
in y+z
Run Code Online (Sandbox Code Playgroud)
工作完全正常,而
aaa = let y = 1+2
z = 4+6
in let f = 3
e = 3
in e+f
Run Code Online (Sandbox Code Playgroud)
给我错误:"表达式中的语法错误(意外的`=')"
我编写了以下代码来读取整数数组stdin:
use std::io::{self, BufRead};
fn main() {
let stdin = io::stdin();
for line in stdin.lock().lines() {
let xs: Vec<i32> = line.unwrap()
.trim()
.split(' ')
.map(|s| s.parse().unwrap())
.collect();
println!("{:?}", xs);
}
}
Run Code Online (Sandbox Code Playgroud)
这很好,但是,我感觉let xs线条有点长,所以我把它分成两部分:
use std::io::{self, BufRead};
fn main() {
let stdin = io::stdin();
for line in stdin.lock().lines() {
let ss = line.unwrap().trim().split(' ');
let xs: Vec<i32> = ss.map(|s| s.parse().unwrap()).collect();
println!("{:?}", xs);
}
}
Run Code Online (Sandbox Code Playgroud)
这没用!Rust回复了以下错误:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:6:18
|
6 …Run Code Online (Sandbox Code Playgroud) 我发现在Swift中声明变量的这些不同方法非常有趣:
// METHOD 1
var dogName: String = "Charlie"
// METHOD 2
var dogName: String {
return "Charlie"
}
// METHOD 3
let dogName = {
return "Charlie"
}
// METHOD 4
var dogName: String = {
return "Charlie"
}()
Run Code Online (Sandbox Code Playgroud)
显然方法3声明了一个让我们知道差异; 但为什么Swift允许方法4?
这四种方法有什么区别?
我在方法2和方法4之间特别混淆.另外,为什么方法3与方法4相比失去了最后的括号?
我今天在Haskell 遇到了令人沮丧的事情.
这是发生的事情:
尝试使用类型签名定义函数:
Prelude Control.Monad> let myFilterM f m = do {x <- m; guard (f x); return x} :: (MonadPlus m) => (b -> Bool) -> m b -> m b
<interactive>:1:20:
Inferred type is less polymorphic than expected
Quantified type variable `b' is mentioned in the environment:
m :: (b -> Bool) -> m b -> m b (bound at <interactive>:1:16)
f :: (m b …Run Code Online (Sandbox Code Playgroud) 我应该首先提一下,我对Haskell很新.有没有特别的理由let在Haskell中保留表达式?
我知道Haskell摆脱了rec对应于let语句的Y-combinator部分的关键字,表明它是递归的.为什么他们没有let完全摆脱声明呢?
如果他们这样做,陈述在某种程度上似乎会更加迭代.例如,类似于:
let y = 1+2
z = 4+6
in y+z
Run Code Online (Sandbox Code Playgroud)
只会是:
y = 1+2
z = 4+6
y+z
Run Code Online (Sandbox Code Playgroud)
对于熟悉函数式编程的人来说,哪个更易读,更容易阅读.我能想到保持它的唯一原因是这样的:
aaa = let y = 1+2
z = 4+6
in y+z
Run Code Online (Sandbox Code Playgroud)
如果没有这个let,我认为最终会出现模棱两可的语法:
aaa =
y = 1+2
z = 4+6
y+z
Run Code Online (Sandbox Code Playgroud)
但是如果Haskell没有忽略空格,并且代码块/范围与Python类似,它是否能够删除let?
是否有更强的理由留下来let?
对不起,如果这个问题看起来很愚蠢,我只是想了解更多关于它为什么存在的问题.
我想在循环中重新绑定一个特殊变量.现在,通常,这是使用a完成的let.
(let ((*read-eval* nil))
(do-something-here))
Run Code Online (Sandbox Code Playgroud)
但由于loop宏有这些好的with条款,我想我可能会在那里这样做.表达式(macroexpand '(loop with *read-eval* = nil))最终将绑定扩展为a let,因此它肯定会对我的实现有所帮助.但我在标准中找不到任何表明这是标准化行为的内容.所以,我想,我的问题是:
(loop with *read-eval* = nil
for i from 1 to 10
do (something-involving-the-read-function))
Run Code Online (Sandbox Code Playgroud)
是否需要符合实现来修改现有*read-eval*变量,或者是否存在可能创建同名新词法变量的风险?
我正在阅读文档示例之间的区别,var并let测试当调用未声明的变量时,全局作用域自动为其提供声明(这就是为什么以下代码段不会在任何变量中引发错误):
x = 3;
console.log(x);
(function() {
y=x+39;
})()
console.log(y);Run Code Online (Sandbox Code Playgroud)
但是,当let在同一全局范围内赋值后声明一个变量时:
x=3;
let x = 42;
console.log(x);Run Code Online (Sandbox Code Playgroud)
抛出以下错误之一:
ReferenceError:
x未定义(Chromium)ReferenceError:
x在初始化之前无法访问词法声明(Firefox)
我明白这let不允许x提升,但由于它先前被引用(暗示来自全局范围的自动声明),在这种情况下不应该重新声明吗?
SyntaxError:
x已声明标识符
因此抛出上面的错误?
我也明白,在严格模式下,第一个片段会抛出一个ReferenceError,所以这是否意味着let在全局范围内强制执行严格模式的特定规则(所有变量都需要声明)?
最近ES6发布后,许多消息来源建议我使用"const"和"let"而不是"var",我应该停止在我的JavaScript中使用"var".我想知道的是,如果"var"在所有观点上都没有"let"的优势那么他们为什么不修复var,或者甚至弃用"var"而不是让它们彼此并排?
鉴于这一系列的Haskell代码,我的任务是将其评估为最简单的形式.
let g h k = (\x -> k (h x)) in g (+1) (\x -> x+x) 20
Run Code Online (Sandbox Code Playgroud)
我已经得到了答案(当然在GHCI中我自己进行了评估): 42
但是,我希望更好地了解评估在这里如何运作.一般来说,我想我知道如何(简单)让表达式工作:
例
a = let y = 5 in y * 5 -- a == 25
Run Code Online (Sandbox Code Playgroud)
该计算结果为25,因为我们绑定y到的价值5和a被分配到的值y*5(后部分in).绑定y = 5仅在范围内有效let.
到目前为止,唯一的解释(至少评估为42)如下:
let g h k = (\x -> k (h x)) in g (+1) (\x -> x+x) 20
Run Code Online (Sandbox Code Playgroud)
g 是 (\x -> k (h x)) …let ×10
haskell ×4
ecmascript-6 ×3
javascript ×3
scope ×2
var ×2
common-lisp ×1
deprecated ×1
global ×1
lambda ×1
lifetime ×1
loops ×1
rust ×1
swift ×1
swift3 ×1
types ×1