2015-09-17 29 views
0

在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 

那麼,什麼實例變量賦值給一個局部變量,而不是直接使用實例變量的原因是什麼?

回答

4

因爲@filename可能會在我們檢查它是否不爲零(如果@filename)和我們訪問它的時間之間同時更改。 Crystal是一個編譯好的程序,@filename不是它所期望的類型,那麼程序會因爲段錯誤而崩潰。

通過分配一個局部變量,我們確保變量確實存在。

+1

有關此問題的更多討論,另請參閱https://github.com/manastech/crystal/issues/477。 –