魔術數字

维基百科,自由的百科全书
跳转至: 导航搜索

程式設計中所謂的魔術數字(magic number)是指直接寫在程式碼裡的具體數值(如「10」「123」等以數字直接寫出的值)。雖然程式作者寫的時候自己能了解數值的意義,但對其他程式員而言,甚至製作者本人經過一段時間後,會難以了解這個數值的用途,只能苦笑諷刺「這個數值的意義雖然不懂,不過至少程式能夠執行,真是個魔術般的數字」而得名。

因為下述理由,一般認為程式碼中不應該含有魔術數字。

  • 數值的意義難以了解
  • 數值需要變動時,可能要改不只一個地方

例1:

price_tax = 1.05 * price

例1是對輸入的價格(price)計算含(price_tax)售價的程式。 但稅率並不是萬年不變,當政府調整稅率時,會有修改程式的必要。 這裡「1.05」就是一種魔術數字,「為什麼是1.05」會讓人無法馬上了解。 下面是去掉魔術數字的範例,程式容易了解也容易修正。

例1 (修正):

TAX = 0.05
price_tax = (1.0 + TAX) * price

例2:

setColor("text", 0xffffff)

例2是設定以白色顯示程式碼。 然而十六進位的色碼0xffffff很難直覺看懂是「白色」,故也算是一種魔術數字。 下面是一種拿掉魔術數字的方式。

例2 (修正):

white = 0xffffff
setColor("text", white)

像這樣,將魔術數字置換成常數列舉型別是經常用來解決魔術數字問題的手段。由於常數可以賦予易懂的名稱,可使幫助閱讀者了解數值的意義。 當然,在程式初始化部分定義的常數列表不稱為魔術數字。

例3:

year = (new Date()).getYear() - 1911;

例3是用來取得今年之中華民國紀年的程式碼。 然而將「1911」寫死在程式碼裡並不盡理想,例如程式不易在其他國家使用等。 下面是一種拿掉魔術數字的方式。

function getTaiwanYear() { return (new Date()).getYear() - 1911; }
year = getTaiwanYear();

這個範例則使用函式來包裝整段計算中華民國紀年的邏輯,函式內則直接保留數值1911。 這樣做的好處是在程式中可藉由getTaiwanYear()這個函式名稱更容易了解程式意圖,並對未來若需支援其他國家時保留彈性。 例如,需要使用日本曆時,可只抽換函式部分而不動到程式所有參考年份運算的地方。

另外,在 一些程式語言中,10經常直接作為「真」、「假」的意義(布林值)使用,有時候也不被認為是魔術數字。 (但近年的語言多半建議使用truefalse替代。)