2016-12-26 60 views
0

在Go中,您沒有聲明您需要實現接口,您只需執行它(它被稱爲「結構類型」,類似於動態語言中的「duck typing」)。 如果你想強制一個類型實現一個接口(例如,當你在C#或Java中繼承一個接口),該怎麼辦?換句話說,如果忘記實現一個接口(或者弄錯簽名)是一個錯誤,你想盡早發現錯誤。什麼是最好的方式來做到這一點?你可以這樣做強制執行Go類型來實現接口

+1

寫一個測試。除非類型實現上述接口,否則測試不會通過。 – ain

回答

2

最好的辦法是嘗試的類型的實例分配到要確保類型A實現Stringer接口變量

例如一個接口。

你可以做這樣的

var _ Stringer = new(A) //or 
var _ Stringer = A{} 

下面是示例程序,在這個例子中A實現接口,B

package main 

import (
    "fmt" 
) 

type Stringer interface { 
    String() string 
} 

type A struct { 
} 

func (a A) String() string { 
    return "A" 
} 

type B struct {} 


var _ Stringer = new(A) 
var _ Stringer = new(B) 

func main() { 

    fmt.Println("Hello, playground") 
} 

在這裏打球鏈接:play.golang

+1

感謝@Sarathsp那個優雅的解決方案。我瞭解到,它有時被稱爲金絲雀測試(來自礦區貧民窟的金絲雀,會因煤氣中毒而快速死亡,以警告地雷)。 –

+0

我假設虛擬變量將被編譯器丟棄,並且不消耗空間和CPU時間。我想,如果有疑問,它總是可以移動到_test.go文件。 –

+0

這將被編譯器丟棄。移動到測試文件是你的電話,但我會建議把它放在那裏,因爲它使明確的實現要求:D, 順便說一句,你我的嘗試'var _ St​​ringer =(* A)(nil)'如果內存是關注:D –

0

要完成@Sarathsp說: 基本上,通過聲明一個虛擬變量(下劃線表示它不是而分配你的類型給它的一個實例的接口類型的使用),你會得到非常明確的編譯時錯誤:在您使用的類型所需的接口

type MyType struct { 
    } 

    func (*MyType) Read() { 

    } 

    var _ io.Reader = &MyType{} 


cannot use MyType literal (type *MyType) as type io.Reader in assignment: 
     *MyType does not implement io.Reader (missing Read method) 

Or 

cannot use MyType literal (type *MyType) as type io.Reader in assignment: 
     *MyType does not implement io.Reader (wrong type for Read method) 
       have Read() 
       want Read([]byte) (int, error) 
相關問題