2015-01-12 126 views
11

我試圖識別一個結構與字符串值(名稱)。 reflect.TypeOf返回Typegolang類型使用reflect.Typeof斷言()

但類型斷言需要type

如何鑄造Typetype

或有任何建議來處理它?

http://play.golang.org/p/3PJG3YxIyf

package main 

import (
"fmt" 
"reflect" 
) 
type Article struct { 
    Id    int64  `json:"id"` 
    Title   string  `json:"title",sql:"size:255"` 
    Content  string  `json:"content"` 
} 


func IdentifyItemType(name string) interface{} { 
    var item interface{} 
    switch name { 
    default: 
     item = Article{} 
    } 
    return item 
} 

func main() { 

    i := IdentifyItemType("name") 
    item := i.(Article) 
    fmt.Printf("Hello, item : %v\n", item) 
    item2 := i.(reflect.TypeOf(i)) // reflect.TypeOf(i) is not a type 
    fmt.Printf("Hello, item2 : %v\n", item2) 

} 
+6

這在Go中是完全不可能的。類型斷言僅聲明編譯時常量固定的靜態類型。你必須重做你的解決方案。 – Volker

+0

感謝您的評論。這很清楚! – dorajistyle

回答

4

類型斷言在語法上採用括號中的類型,而不是表達式。所以這是一個語法錯誤。

您似乎在嘗試使用在運行時計算的值執行類型斷言。那有意義嗎?讓我們來思考一個類型斷言是什麼。

A型斷言由兩件事情:

  1. 在編譯時:它會導致所產生的表達具有期望編譯時間類型。表達式x.(T)具有編譯時型T。這可以讓你做出你可以用T類型做的表情,而這種類型的x可能無法做到。
  2. 在運行時:它檢查值是否不是nil,實際上是給定的類型,如果不是,它會導致恐慌。

第一部分顯然對運行時計算的類型沒有意義。結果表達式的編譯時類型不能依賴於編譯時未知的內容。

第二個(運行時檢查)可以使用在運行時計算的類型完成。例如:

if reflect.TypeOf(x) != someTypeComputedAtRuntime { 
    panic(42) 
} 
5

如果您需要打開外部接口{}的類型,您不需要反射。

switch x.(type){ 
    case int: 
    dosomething() 
} 

...但如果你需要在一個界面上的屬性的類型轉換,那麼你可以這樣做:

s := reflect.ValueOf(x) 
for i:=0; i<s.NumValues; i++{ 
    switch s.Field(i).Interface().(type){ 
    case int: 
     dosomething() 
    } 
} 

我還沒有找到一個乾淨的方式,我會愛知道它是否存在。

0

我認爲你可以使用的valueOf解決這個

item2 := reflect.ValueOf(i) 
fmt.Printf("Hello, item2 : %v\n", item2) 
+1

ValueOf()返回一個類型reflect.Value,而不是接口的實際底層類型... – MonkeyButter

1

如果你能處理的噪音,實現所有類型的例如實現額外的方法'Type()string',你可以這樣做:

 ve := &ValidationError{} 
     nf := &NotFound{} 

     switch err.Type() { 
     case ve.Type() : 
      SendBadRequest(w, err) 
     case nf.Type() : 
      http.NotFound(w, r) 
     default: 
      SendInternalError(w, err) 
     } 
     return