欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

為什么說「動態類型一時爽,代碼重構火葬場」?

林子帆2年前15瀏覽0評論

打個比方,便于理解

你寫一個允許傳入動態類型的函數給別人用,就如同給一張簽了名的空白支票別人一樣危險,別人愛寫什么數字上去都行。

正式說明

以Facebook為例,Facebook有一種數據類型叫做FBID,是一個64位的整數,用作任何對象的唯一ID。

在Facebook把無類型的PHP轉化為有類型的Hack之前,很多人不知道FBID是整數還是字符串,于是有些函數用整數接收FBID,另外一些函數用字符串。

到最后,函數間傳遞的FBID到底是什么類型已經說不清楚。

導致的結果就是:你寫一個函數,中間接收了一個FBID的數組,你永遠不可能知道FBID屬于哪種類型,甚至可能是混合類型的。

在語義上這絕對是有問題的,但神奇的PHP在做整數和字符串“==”比較時會自動把字符串隱式轉換為整數,所以原本不應該相等的兩種類型FBID可能會被判定為相等。不過如果用===的話,不同類型自然不相等。因為很多人不注意細節,使用==而非===,所以如果假設你接收了一個FBID的數組,然后調用別人的函數來去重,你猜“123”和123會不會被當作重復而去掉?你不可能猜到,因為你不知道別人用什么做對比。

這使得當時Facebook的PHP代碼存在大量難以發現的bug,而且沒人敢去修。你說你這里FBID一定是整數,然后收到字符串就拋異常?你猜你這一改Facebook哪些功能會掛掉?你不可能知道……所以你不敢改。

最終Facebook把PHP逐步轉化為Hack,把FBID存儲為整數,大家就可以放心地把FBID傳來傳去不用擔心出問題了。如果你嘗試拿FBID跟另外一個字符串或整數比較,你的代碼在靜態分析階段就會報錯。你一定要比較,就必須進行顯式類型轉換后再做比較。

同理,Facebook把JavaScript改造為Flow,但FBID在JavaScript里面必須存儲為字符串,因為JavaScript存儲不了64位整數,可能會轉換為浮點數存儲,然后丟失精度。在此之前,有人不知道FBID在JavaScript不能存為整數,然后引發各種難以復現的bug。

如果你不懂Hack或Flow,可以用現在主流的TypeScript做參考。我認為這是現在最好的折衷方案。語言本身是支持動態類型的,但通過類型注釋來讓類型穩定的變量和參數變為有類型,你不加類型注釋的時候還能靈活使用動態類型。

為什么要保留動態類型?

因為你在開發新功能時,可能你只是在探索,具體數據結構還沒有定下來,不需要聲明完整的數據結構類型信息能為你節省不少改來改去的時間。與之對比的是那些C++和Java操作JSON的代碼,必須處處聲明現在預期讀取出來的變量是什么類型,你稍微改一下JSON的結構就要改對應的類型聲明,這真的很麻煩。

以上,希望對你有用!