范围(2,5)和范围(2; 5)之间的区别

difference between range(2,5) and range(2;5)

模板

range(2;5)

生产:

2
3
4

没那么有趣,因为这在手册中有解释。但是对于命令式程序员来说只是时间问题,他会错误地用逗号分隔参数(实际上我看错了手册,所以这是我的第一次尝试),并尝试模板:

range(2, 5)

产生惊喜:

0
1
0
1
2
3
4

那是什么?怎么样defined/explained?

“逗号”运算符(如 2,5 中所示)生成一个流。所以 2,5 发出两个整数,这就是为什么 [2,5] 求值为两个整数的数组。

通常,如果 E/1 已使用等同于 def E($x): 的形式定义(即,作为“常规”函数),则 E(a,b) 会发出流 E(a) 后跟流 E(b).

确实 range/1 已被定义为“常规函数”。

非常规函数

下面是一个非常规函数的例子:

# Emit a single JSON object ("bow" is short for "bag of words")
def bow(stream): 
  reduce stream as $word ({}; .[($word|tostring)] += 1);

注意这里的函数参数 (stream) 被传递给 reduce,它当然以特殊方式处理它的第一个参数。

由于def E($x):等同于def E(x): x as $x,定义bow

def bow($s): reduce $s as $word ({}; .[($word|tostring)] += 1);

会有完全不同的(和无用的)语义。

peak 的答案是正确的,但我觉得它掩盖了答案的最基本部分......逗号根本不用于分隔 jq 中的函数参数,因为它“已经被采用”并且 jq 很少语法重载。

因为所有函数都隐含地接受一个流(输入为 .)并求值到一个流,所以大量函数在句法上是 0-adic(例如 tostring),并且大多数其余的在句法上是 1-adic(例如 split(str) 将分隔符作为参数,并且隐式地使用该分隔符拆分值)。对于像 rangesub 这样接受多个显式参数的罕见函数,分号用作分隔符,而不是逗号。

而且由于 jq 不是一种面向语句的语言,因此 几乎 分号的唯一用法。它出现的唯一其他地方是标记函数定义的结尾,这不会引起太多混淆。