Julia 是如何解释 10:1 的?
How does Julia interpret 10:1?
我长期专注于 R,其中 :
(冒号)运算符创建从第一个参数到第二个参数的整数序列:
1:10
# [1] 1 2 3 4 5 6 7 8 9 10
10:1
# [1] 10 9 8 7 6 5 4 3 2 1
注意到这在 Julia 中似乎同样有效,我 运行 陷入了一个错误:
1:10 .== 10:1
DimensionMismatch("arrays could not be broadcast to a common size")
因为:
10:1
输出
10:9
我对这怎么会发生感到困惑。不需要使用 10:-1:1
似乎很自然——为什么 Julia 认为 10:9
是对 10:1
的正确解释?
在 Julia 中,我们假设 a:b
构造一个步长为 1 的范围,所以
10:1
是一个 UnitRange
,它应该是一个空范围。由于 a:a-1
也是一个空范围,因此它等效于 a:b
其中 b<a
,
请查看源代码 here.
julia> dump(10:1)
UnitRange{Int64}
start: Int64 10
stop: Int64 9
julia> dump(10:-1:1)
StepRange{Int64,Int64}
start: Int64 10
step: Int64 -1
stop: Int64 1
这里的10:-1:1
是步长为-1的StepRange
,我认为这样更准确自然地表达了“10比1”的思想。
Julia 不是 R。还有其他语言对冒号语法的解释与 Julia 相似。 MATLAB 将 10:1
视为空数组,Python 的切片语法(虽然在其他方面有所不同)也将使用 10:1
的索引视为空选择。 Julia 选择规范化空整数范围,使得开始和停止之间的差异始终为 -1
,因此它变为 10:9
。
所以我不认为 10:1
有明确的解释。然而,在我看来,有一些非常有利于 Julia 解释的论据:
空范围10:9
用于表示some APIs中索引9和10之间的位置。
范围是 Julia 中的核心构造,for x in 1:10
绝对且明确地必须与等效的 C 循环一样快。因为语法 x:y
总是递增 1(从不递减 1),Julia(和 LLVM)在编译 for 循环时可以利用该常量来实现进一步的优化。使这不是常量——或者更糟的是,根据端点的值在 UnitRange
和 StepRange
之间动态切换会阻碍这种优化或类型不稳定。
就个人而言,我发现 R 的解释与您发现 Julia 的一样令人惊讶。我认为需要明确表示您想要 -1
的步骤在可读性和错误预防方面都是有利的。但我承认我对先前语言的体验与你的一样有偏见。
我长期专注于 R,其中 :
(冒号)运算符创建从第一个参数到第二个参数的整数序列:
1:10
# [1] 1 2 3 4 5 6 7 8 9 10
10:1
# [1] 10 9 8 7 6 5 4 3 2 1
注意到这在 Julia 中似乎同样有效,我 运行 陷入了一个错误:
1:10 .== 10:1
DimensionMismatch("arrays could not be broadcast to a common size")
因为:
10:1
输出
10:9
我对这怎么会发生感到困惑。不需要使用 10:-1:1
似乎很自然——为什么 Julia 认为 10:9
是对 10:1
的正确解释?
在 Julia 中,我们假设 a:b
构造一个步长为 1 的范围,所以
10:1
是一个 UnitRange
,它应该是一个空范围。由于 a:a-1
也是一个空范围,因此它等效于 a:b
其中 b<a
,
请查看源代码 here.
julia> dump(10:1)
UnitRange{Int64}
start: Int64 10
stop: Int64 9
julia> dump(10:-1:1)
StepRange{Int64,Int64}
start: Int64 10
step: Int64 -1
stop: Int64 1
这里的10:-1:1
是步长为-1的StepRange
,我认为这样更准确自然地表达了“10比1”的思想。
Julia 不是 R。还有其他语言对冒号语法的解释与 Julia 相似。 MATLAB 将 10:1
视为空数组,Python 的切片语法(虽然在其他方面有所不同)也将使用 10:1
的索引视为空选择。 Julia 选择规范化空整数范围,使得开始和停止之间的差异始终为 -1
,因此它变为 10:9
。
所以我不认为 10:1
有明确的解释。然而,在我看来,有一些非常有利于 Julia 解释的论据:
空范围
10:9
用于表示some APIs中索引9和10之间的位置。范围是 Julia 中的核心构造,
for x in 1:10
绝对且明确地必须与等效的 C 循环一样快。因为语法x:y
总是递增 1(从不递减 1),Julia(和 LLVM)在编译 for 循环时可以利用该常量来实现进一步的优化。使这不是常量——或者更糟的是,根据端点的值在UnitRange
和StepRange
之间动态切换会阻碍这种优化或类型不稳定。就个人而言,我发现 R 的解释与您发现 Julia 的一样令人惊讶。我认为需要明确表示您想要
-1
的步骤在可读性和错误预防方面都是有利的。但我承认我对先前语言的体验与你的一样有偏见。