错误:顶级未定义的局部变量或方法'var'

时间:2019-10-29 13:34:00

标签: crystal-lang

我是Crystal编程语言的新手。

每当我运行此代码时:

var = ARGV.find { |x| x.split(".").size == 4 } || "0.0.0.0"

ARGV.delete(var)
Addr = var.split(".").map { |x| x.to_i { 0 } }.join(".")
p Addr

使用水晶时,我得到一个错误:

Showing last frame. Use --error-trace for full trace.

In q.cr:4:8

 4 | Addr = var.split(".").map { |x| x.to_i { 0 } }.join(".")
            ^--
Error: undefined local variable or method 'var' for top-level

但是每当我省略最后一行p Addr或将var替换为Var时,代码似乎都可以正常工作。

水晶版本:

Crystal 0.31.1 (2019-10-21)

LLVM: 9.0.0
Default target: x86_64-pc-linux-gnu

我的代码有什么问题?

1 个答案:

答案 0 :(得分:5)

这是一个小问题,我们希望将来会得到更好的错误消息。

这个难题的第一步是要了解var是局部变量,因为它以小写字母开头,而Addr是常量,因为它以大写字母开头。

由于常量初始化程序的原因,因此=符号后面的代码在常量分配中会在第一次访问该常量时延迟运行。因此,它们存在于自己的作用域中,因此无法引用顶级作用域中定义的局部变量。

因此,您的示例有三种解决方法。首先也通过将Addr命名为addr来使其成为局部变量。通过调用var将其Var提升为常数。或者第三次将整个代码放入常量初始化程序中:

Addr = begin
  ip = ARGV.find { |arg| arg.count('.') == 3 } || "0.0.0.0"
  ARGV.delete(ip)
  ip.split('.').map { |part| part.to_i { 0 } }.join('.')
end

这三个最好的哪个主要取决于口味和程序的结构。