2017-03-05 45 views
1

例如:轉到郎反思如何識別接口的基本類型

package main 

import (
    "fmt" 
    "reflect" 
) 

func main() { 

    arr := []int{} 

    var arrI interface{} = arr 

    arrValuePtr := reflect.ValueOf(&arrI) 
    arrValue := arrValuePtr.Elem() 

    fmt.Println("Type: ", arrValue.Type()) // prints: "Type: interface{} 
    fmt.Println("Interface value: ", arrValue.Interface()) // prints: "Interface value: []" 


    arrValue.Set(reflect.Append(arrValue, reflect.ValueOf(55))) 
    // error: panic: reflect: call of reflect.Append on interface Value 
} 

那麼,有沒有認識到arrValue是切片值,而不是接口{}值的方法嗎? https://play.golang.org/p/R_sPR2JbQx

+0

爲什麼要採用'interface {}'的指針? 'arrValue:= reflect.ValueOf(arrI)'給我'類型:int []':https://play.golang.org/p/5L1NqItNh1 – myaut

+0

讓我們從這個例子開始:https://play.golang。組織/ p/Nhabg31Sju。在這個例子中,如果我不將arr作爲指針傳遞,我會在appendToSlice方法內部得到「reflect.Value.Set using unaddressable value」。 現在我想概括一下這個解決方案。我想將任何切片傳遞給此方法(忽略只添加int的事實)。更新示例:https://play.golang.org/p/WGtfjpW0EN – agnor

回答

2

正如您所看到的,您不能直接附加到界面。所以,你想獲得與接口相關的值,然後使用它與Value.Append

arr := []int{} 

var arrI interface{} = arr 

arrValuePtr := reflect.ValueOf(&arrI) 
arrValue := arrValuePtr.Elem() 

fmt.Println("Type: ", arrValue.Type()) // prints: "Type: interface{} 
fmt.Println("Interface value: ", arrValue.Interface()) // prints: "Interface value: []" 
fmt.Println(reflect.ValueOf(arrValue.Interface())) 
arr2 := reflect.ValueOf(arrValue.Interface()) 
arr2 = reflect.Append(arr2, reflect.ValueOf(55)) 
fmt.Println(arr2) // [55] 
+0

原始切片仍不受影響。 fmt.Println(arr)// [] https://play.golang.org/p/f6mjuXl0V3 – agnor

+0

它無法修改。 'arrI'是原始片的地址的*副本*。記住,當你追加到一個切片時,原始切片不會被修改,因此需要一個作爲。你可以做的唯一事情就是說,初始化'arr:= [] int {1}',修改'arr2'中的值,並看到'arr'中的修改。 – Fabien

+0

好的。我現在明白了。謝謝。 – agnor