2015-08-20 33 views
3

我想知道一個具體類型是否實現了一個specefic接口並將其打印出來。 我寫了一個自定義結構(MyPoint)不是接口類型的示例[0]。 MyPoint具有如圖io.Reader的接口中定義的閱讀功能:檢查變量實現接口而不編譯

type MyPoint struct { 
    X, Y int 
} 

func (pnt *MyPoint) Read(p []byte) (n int, err error) { 
    return 42, nil 
} 

的目的是獲得的,在混凝土p類型實現接口io.Writer的信息。 因此,我寫了一個簡短的主要步驟來獲得支票的真實性。

func main() { 
    p := MyPoint{1, 2} 
} 

第一個想法是與反射的幫助和一個類型開關和添加check(p)向主函數來檢查它。

func checkType(tst interface{}) { 
    switch tst.(type) { 
    case nil: 
     fmt.Printf("nil") 
    case *io.Reader: 
     fmt.Printf("p is of type io.Reader\n") 
    case MyPoint: 
     fmt.Printf("p is of type MyPoint\n") 
    default: 
     fmt.Println("p is unknown.") 
    } 
} 

輸出結果爲:p is of type MyPoint。經過一番研究,我知道我應該預料到因爲Go的類型是靜態的,所以p的類型是MyPoint而不是io.Reader。除此之外,io.Reader是一種與MyPoint類型不同的接口類型。

我發現了一個解決方案,例如在[1]中檢查MyPoint是否可以在編譯時成爲io.Reader。有用。

var _ io.Reader = (*MyPoint)(nil) 

但這不是我想要的解決方案。像下面的嘗試也失敗了。我認爲這是因爲上述原因,不是嗎?

i := interface{}(new(MyPoint)) 
    if _, ok := i.(io.Reader); ok { 
     fmt.Println("i is an io.Reader") 
} 
pType := reflect.TypeOf(p) 
if _, ok := pType.(io.Reader); ok { 
    fmt.Println("The type of p is compatible to io.Reader") 
} 

readerType := reflect.TypeOf((*io.Reader)(nil)).Elem() 
fmt.Printf("p impl. Reader %t \n", pType.Implements(readerType)) 

存在一種解決方案來檢查p是否實現了接口而不編譯?我希望有人能幫助我。

[0] http://play.golang.org/p/JCsFf7y74C(固定) http://play.golang.org/p/cIStOOI84Y(舊)

[1] Explanation of checking if value implements interface. Golang

+0

編輯的「固定」 [0]鏈接,使其工作的https://玩。golang.org/p/zjPUT_POF- –

回答

5

這是完全可以做到的,你想用反映包什麼。這裏是一個例子:

package main 

import (
    "fmt" 
    "io" 
    "reflect" 
) 

type Other int 

type MyPoint struct { 
    X, Y int 
} 

func (pnt *MyPoint) Read(p []byte) (n int, err error) { 
    return 42, nil 
} 

func check(x interface{}) bool { 
    // Declare a type object representing io.Reader 
    reader := reflect.TypeOf((*io.Reader)(nil)).Elem() 
    // Get a type object of the pointer on the object represented by the parameter 
    // and see if it implements io.Reader 
    return reflect.PtrTo(reflect.TypeOf(x)).Implements(reader) 
} 

func main() { 

    x := MyPoint{0, 0} 
    y := Other(1) 

    fmt.Println(check(x)) // true 
    fmt.Println(check(y)) // false 
} 

棘手的一點是要注意如何處理指針。

+0

剛做'_,ok:= x。(io.Reader)'有什麼問題?如果'x'實現了'io.Reader',那麼'ok'是真的,否則就是false。 –

+0

你試過了嗎?它似乎沒有工作... –

3

存在一種解決方案來檢查p是否實現了接口而不編譯?

是:代碼:-)

的仔細閱讀怎麼可能可能呢?如果p的方法集涵蓋i,則p實現了一些接口i。你將永遠需要編譯代碼。

我假設你想在編譯期間失敗,而不是在運行時打印。 竅門就是可與Implements方法的reflect.Type進行測試的非零接口類型:

pt := reflect.TypeOf(&MyPoint{}) 
ioReaderType := reflect.TypeOf((*io.Reader)(nil)).Elem() 
fmt.Println(pt.Implements(ioReaderType)) // ==> true 

http://play.golang.org/p/2Qcpfjm4ft