2016-08-28 1 views
1

reflect.New[]interface{}[]int과 같게 만들고 다른 슬라이스에 추가하고 싶습니다.반영하는 방법. 슬라이스를 새로 고치고 반영합니다. 추가 슬라이스를 소스 슬라이스에 붙여 넣으십시오.

내 코드에 오류가 있어야하지만 올바른 방법과 정확하게 reflect.Newreflect.AppendSlice 사용법을 이해하는 방법을 알지 못합니다.

package main 

import (
    "fmt" 
    "reflect" 
) 

func main() { 
    var a []int 
    var value reflect.Value = reflect.ValueOf(&a) 


    if !value.CanSet() { 
     fmt.Println("go here", value.CanSet()) 
     value = value.Elem() 
     fmt.Println("go here", value.CanSet()) 
    } 
    fmt.Println("go here", value.Type())  
    s := reflect.New(value.Type()) 
    fmt.Println("go here", s.Elem()) 
    value = reflect.AppendSlice(value, reflect.ValueOf(s.Elem())) 
    value = reflect.AppendSlice(value, reflect.ValueOf([]int{1, 2}))     
    value = reflect.AppendSlice(value, reflect.ValueOf([]int{3, 4, 5, 6, 7, 8, 9})) 

    fmt.Println(value.Kind(), value.Slice(0, value.Len()).Interface()) 
    //>>slice [1 2 3 4 5 6 7 8 9] 
} 

하지만 에러를 제공한다 :

panic: reflect: call of reflect.AppendSlice on struct Value 

goroutine 1 [running]: 
panic(0x100a60, 0x1040e1a0) 
    /usr/local/go/src/runtime/panic.go:500 +0x720 
reflect.flag.mustBe(0x99, 0x17) 
    /usr/local/go/src/reflect/value.go:201 +0xe0 
reflect.AppendSlice(0xfa7e0, 0x1040e130, 0x197, 0x1116a0, 0x1040e190, 0x99, 0x0, 0x0, 0x0, 0x2) 
    /usr/local/go/src/reflect/value.go:1825 +0x60 
main.main() 
    /tmp/sandbox476529744/main.go:21 +0x800 

golang playground

+0

주요 아이디어는이다 ] int는 전환 할 수 없습니다. [] 인터페이스 {}에 오류가 발생했습니다. 암시 적 변환이 없기 때문에 이러한 슬라이스를 반영하거나 첨부 할 수 없습니다. – lofcek

답변

2

패닉이 라인이다

value = reflect.AppendSlice(value, reflect.ValueOf(s.Elem())) 

s.Elem()reflect.Value이다. AppendSlice에 전화에서 직접이 값을 사용

value = reflect.AppendSlice(value, s.Elem()) 

하지 기본 []int를 들어, reflect.Valuereflect.Value를 반환 reflect.ValueOf(s.Elem()) 표현합니다. 라인 (21)의

playground example

0

오류 :

value = reflect.AppendSlice(value, reflect.ValueOf(s.Elem())) 

참조 문서 : 당신이 값을 덤프 때

func AppendSlice(s, t Value) Value 
The slices s and t must have the same element type. 

, 당신은 참조하십시오

Var dump s.Elem(): []int(nil) 
Var dump reflect.ValueOf(s.Elem()): {typ:0xfa840 ptr:0x1040e160 flag:407} 
Var dump value: []int(nil) 

그래서 당신은 단지 필요,
참조 : https://play.golang.org/p/KwXRxGyswg

1

이 작업 샘플로 시험 인쇄를 해보십시오 (The Go Playground) :

package main 

import (
    "fmt" 
    "reflect" 
) 

func main() { 
    s := reflect.New(reflect.TypeOf([]interface{}{})).Elem() 
    s = reflect.Append(s, reflect.ValueOf(1)) 
    s = reflect.AppendSlice(s, reflect.ValueOf([]interface{}{2, 3, 4, 5, 6, 7, 8, 9})) 
    fmt.Println(s) 
} 

출력 :

[1 2 3 4 5 6 7 8 9] 

그리고 참조 : https://github.com/golang/go/wiki/InterfaceSlice :

The question then, "Why can't I assign any slice to an []interface{}, when I can assign any type to an interface{}?"

Why?

There are two main reasons for this.

The first is that a variable with type []interface{} is not an interface! It is a slice whose element type happens to be interface{}. But even given this, one might say that the meaning is clear.

Well, is it? A variable with type []interface{} has a specific memory layout, known at compile time.

Each interface{} takes up two words (one word for the type of what is contained, the other word for either the contained data or a pointer to it). As a consequence, a slice with length N and with type []interface{} is backed by a chunk of data that is N*2 words long.

This is different than the chunk of data backing a slice with type []MyType and the same length. Its chunk of data will be N*sizeof(MyType) words long.

The result is that you cannot quickly assign something of type []MyType to something of type []interface{}; the data behind them just look different.