为什么在crystal中需要将实例变量赋值给局部变量?

why is the assignment of instance variables to local variables is need in crystal?

在Crystal编译器源码中看到过这样的代码

def dirname
  filename = @filename
  if filename.is_a?(String)
    File.dirname(filename)
  else
    nil
  end
end

def original_filename
  case filename = @filename
  when String
    filename
  when VirtualFile
    filename.expanded_location.try &.original_filename
  else
    nil
  end
end

def <=>(other)
  self_file = @filename
  other_file = other.filename
  if self_file.is_a?(String) && other_file.is_a?(String) && self_file == other_file
    {@line_number, @column_number} <=> {other.line_number, other.column_number}
  else
    nil
  end
end

那么,为什么要将实例变量赋值给局部变量而不是直接使用实例变量呢?

因为@filename 可能在我们检查它是否不为 nil(如果@filename)和我们访问它的时间之间同时更改。 Crystal 作为编译程序,@filename 不是它预期的类型,那么程序会因段错误而崩溃。

通过分配给局部变量,我们确保该变量确实存在。