2016-10-15 2 views
2

할당하십시오. 동일한 형식의 이미 초기화 된 구조체 포인터의 값을 구조체에 대한 포인터를 할당하려고합니다. 반영, 포인터 구조체 값을

코드 내 시도 내가 같은 런타임 오류가 계속에도 불구하고이

package main 

import (
    "fmt" 
    "reflect" 
) 

type Concrete struct {} 
func (c *Concrete) Do(){} 

type Doer interface { 
    Do() 
} 

func main() { 
    l := ServiceLocator{} 
    l.Register(&Concrete{}) 

    var x Doer 
    if l.Get(&x); x!= nil { 
     fmt.Println("by interface pointer ok") 
    } 

    // This is not possible in my understanding 
    //var z Doer 
    //if l.Get(z); z!= nil { 
    // fmt.Println("by interface ok") 
    //} 

    var y *Concrete 
    if l.Get(y); y!= nil { 
     fmt.Println("by struct pointer ok") 
    } 
} 

type ServiceLocator struct { 
    services []interface{} 
    types []reflect.Type 
    values []reflect.Value 
} 

func (s *ServiceLocator) Register(some interface{}) { 
    s.services = append(s.services, some) 
    s.types = append(s.types, reflect.TypeOf(some)) 
    s.values = append(s.values, reflect.ValueOf(some)) 
} 

func (s *ServiceLocator) Get(some interface{}) interface{} { 
    k := reflect.TypeOf(some).Elem() 
    kind := reflect.TypeOf(some).Elem().Kind() 
    for i, t := range s.types { 
    if kind==reflect.Interface && t.Implements(k) { 
     reflect.Indirect(
     reflect.ValueOf(some), 
    ).Set(s.values[i]) 
    } else if kind==reflect.Struct && k.AssignableTo(t.Elem()) { 
     fmt.Println(reflect.ValueOf(some).Elem().CanAddr()) 
     fmt.Println(reflect.ValueOf(some).Elem().CanSet()) 
     fmt.Println(reflect.Indirect(reflect.ValueOf(some))) 
     reflect.ValueOf(some).Set(s.values[i]) 
    } 
    } 
    return nil 
} 

처럼 간단한 서비스 로케이터를 수행하려면

panic: reflect: reflect.Value.Set using unaddressable value 

는 플레이를 here

필요성을 시도 도움, 많이 고마워! JimB와


도움이 여기에 정보는 Gety의 값을 전달하고 있기 때문에 당신은, y에 직접 포인터의 값을하지 할당 할 수 없습니다 고정 플레이 https://play.golang.org/p/_g2AbX0yHV

답변

3

자사의 주소. y (**Concrete 유형)의 주소를 전달할 수 있으므로 포인터 (*Concrete)를 y에 할당 할 수 있습니다. 값을 직접 할당하는 것이 안전 할 경우, 등록 포인터의 간접 지정을 y에 할당하지만 쓰기 할 주소가되도록 y을 유효한 값으로 초기화해야합니다.

n := 42 
p := &n 

x := new(int) 
// set the value to *x, but x must be initialized 
reflect.ValueOf(x).Elem().Set(reflect.ValueOf(p).Elem()) 
fmt.Println("*x:", *x) 

var y *int 
// to set the value of y directly, requires y be addressable 
reflect.ValueOf(&y).Elem().Set(reflect.ValueOf(p)) 
fmt.Println("*y:", *y) 

https://play.golang.org/p/6tFitP4_jt

+0

와우 네, 분명히 의미가 있습니다 :) 덕분에 많이! –