go 介面靜態與動態校驗

2021-06-27 23:58:55 字數 931 閱讀 9765

go 的介面是duck模型,型別不需要顯式的宣告實現某個介面,只需實現該介面的所有methods,就認為該型別實現該介面。在實際中,大部分介面轉換是靜態的,發生在編譯時刻;go 也支援動態介面轉換,轉換發生在執行時。

比如,需要傳遞*os.file到乙個需要io.reader引數的函式,如果*os.file沒有實現介面io.reader,則程式在編譯期就無法通過;

有些介面裝換發生在執行期,乙個例項就是encoding/json 包,其定義了乙個marshaler介面,當json解析器接收的value實現該介面,就呼叫該value的marshaling 方法轉換,反之則呼叫系統預設的轉換器。這種轉換可以通過go的type型別斷言實現:

if m, ok := val.(json.marshaler); ok  else

if str, ok := value.(string); ok  else if str, ok := value.(stringer); ok

有時我們為了提高程式健壯性或者為了防止介面發生變更而具體實現型別忘記變更導致程式執行時崩潰,我們需要將執行期的校驗提前到編譯期進行,這時可以採用如下方式:

var _ json.marshaler = (*rawmessage)(nil)
此語句將在編譯期將*rawmessage 轉換為json.marshaler,如果介面marshaler發生變化,而rawmessage 沒有變化,編譯將不能通過,從而使我們提前發現問題,進行修改,而不會因為一時疏忽將該問題推遲到執行時才發現。這裡的_僅僅用來進行型別校驗,而不是真的去建立乙個變數。但是不要濫用該方法,該方法僅僅使用在沒有靜態轉換,但是有要保證程式安全的額地方。

靜態與動態

靜態與動態 書中所提解決方案普遍有兩種假設 1 前提條件都是理想情況。在之前的 篩選 中有詳述。2 假設相關因素為靜態。比如一些表演格鬥術者,演示的時候,讓助手按他指定方向攻擊,然後再做反擊。關於第一點,不再贅述,今天主要講第2點。分析問題,首先對現在事物,先分析其存在之合理性。但凡著書者,表演者,...

go反射與介面

在go反射的秘密一文中,我從源 的角度分析了go反射的相關細節,但是在那篇文章中,還是留下了兩個疑問 為什麼typeof函式的實現是直接強制型別轉換?乙個具體型別的變數是如何轉成inte ce的?由於當時的我年少無知,沒能解答出這兩個問題。時過境遷,再次讀書的時候偶然明悟,遂作此文以解惑。讓我們再次...

GO介面定義與實現

如果你看它像只鴨子,那麼它就是乙隻鴨子,這就是duck typeing的概念。如果你是個小朋友你可能會把它當作小黃鴨,如果你是個吃貨可能會把它當作是別的什麼東西。這個概念是有點抽像的。先上段 看看go的介面定義與實現 greenduck.go package duck type greenduck ...