reflect package
in go lang
문용준(myjlms99@gmail.com)
리터럴 관리 기준
Type
Value
“harry potter”
33 int
33
Type
Value
string
harry potter
프로그램 언어들에는 리터럴 즉 값을 데이터 타입별로 관리한다.
변수 정의
Type
Value
var s string
s = “harry potter”
var x int
x = 33 int
x
Type
Value
string
harry potter
변수
33
변수는 데이터 타입을로 정의하고 값을 저장하는 장소를 가진다.
s변수
reflection 이란
var x int
x = 33 Type
Value
int
x변수
33
프로그램언어에서 reflection은 변수가 가진 데이터 타입을 인식하
여 타입 캐스팅 등의 요건을 처리하는 구조
변수 x 의 타입을 처리reflect.TypeOf(x)
reflect.ValueOf(x) 변수 x 의 Value값에 대한 타입을 처리
reflect.ValueOf(x).Int() 변수 x 의 Value에 대한 실제 값을처리
interface{}란
var all_type interface{}
var xi int
var xs string
var xf float32
go lang에서 다른 데이터타입을 받아서 처리할 수 있는 데이터구조
	 all_type = xi
	 fmt.Println(" int ", reflect.TypeOf(all_type))
	 all_type = xs
	 fmt.Println(" string ", reflect.TypeOf(all_type))
	 all_type = xf
	 fmt.Println(" float32 ", reflect.TypeOf(all_type))
예제: interface정의 및 구현(1/3)
type Stringer interface {
	 String() string
}
string을 처리하는 하나의 인터페이스 정의하고 타입을 정의하고 인
터페이스를 구현함
type Binary uint64
// Binary는 Stringer 인터페이스를
구현한다.
func (i Binary) String() string {
	 return strconv.Itoa(i.Get())
}
//int 타입으로 변화
func (i Binary) Get() int {
	 return int(i)
}
예제: interface정의 및 구현(2/3)
func ToString(any interface{}) string {
	 switch vi := any.(type) {
	 case uint64:
	 	 return strconv.Itoa(int(vi))
	 case Binary:
	 	 return strconv.Itoa(int(vi))
	 }
	 return "error"
}
interface{}로 전달받아 처리하는 ToString함수를 정의
예제: interface정의 및 구현(3/3)
ffunc main() {
	 b := Binary(200)
	 s := Stringer(b)
	 var c interface{} = b // 여기서 b 복사본을 만든다.
	 fmt.Println("string ", s.String())
	 fmt.Println(" bbbb", b)
	 fmt.Println("ccccc ", c)
	 fmt.Println("bbbbb string ", b.String())
	 fmt.Println("To String ", ToString(c))
	 fmt.Println(" String ", s.String())
}
실제 실행해조면 동일 한 값을 출력한다
itable: 인터페이스 테이블
b 에 값을 넣고 b를 s에 인터페이스를 넣는다.
인테페이스 구조는 인터페이스 내의 데이터 타입과 실질적인 데이
터 값을 저장하는 구조로 관리된다.
정의 메소드등이 있으면 인터페이스 itable에 메소드도 관리한다.
itable 컴퓨팅
가능한 모든 itable을 전부 미리 구성하는 것이 아닙니다. 구
조를 만들면 실제 런타임에 실행하면서 처리합니다.
컴파일러는 각 타입에 대한 타입 구조 생성
컴파일러는 각 타입에 대한 메소드 구조 생성
런타임시 itable을 검색하여 메소드를 실행
빈 인터페이스 메모리구조
메모리 최적화: 두가지 케이스 조합
인터페이스 메모리 구조
리플렉션 법칙

(The Laws of Reflection)
Rob Pike의 리플렉션 법칙들
http://blog.golang/laws-of-reflection
reflect.TypeOf(interface {}) Type, reflect.ValueOf(interface{}) Value
1. 리플렉션은 인터페이스 값에서 리플렉션 오브젝트로 됩니다.
2. 리플렉션은 리플렉션 오브젝트에서 인터페이스 값으로 됩니다.
3. 리플렉션 오브텍드를 수정하려면 값은 설정할 수 있어야 됩니다.
canSet( ) bool => true 일 경우만 갱신
1. 리플렉션은 인터페이스 값에서 리플렉션
오브젝트로 됩니다.
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println(“type:”, v.Type())
fmt.Println(“kind is float64:”, v.Kind() == reflect.Float64)
fmt.Println(“value:”, v.Float())
//결과
type: float64
kind is float64: true
value: 3.4
유형(Type) 과 유형(Kind)
var x unit8 = ‘x’
v := reflect.ValueOf(x)
fmt.Println(“type:”, v.Type()) // unit8.
fmt.Print(“kind is unit8: ”,v.Kind() == reflect.Unit8) // true.
x = unit8(v.Unit()) // v.Unit returns a unit64.
type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)
fmt.Println(“kind is Int: ”, v.Kind() == reflect.Int) // true
2. 리플렉션은 리플렉션 객체에서 인터페이
스 값으로 됩니다.
// Interface는 interface{} 처럼 v 값을 반환한다.
// func (v value) Interface() interface{}
y := v.Interface().(float64) // y는 float64 타입을 가질 것이다.
fmt.Println(y)
fmt.Printf(“value is %7.1en”, v.Interface()) // 3.4e+00
즉, 인터페이스 메소드는 ValueOf 함수의반대입니다. 그결과는 정적 타입
interface{} 입니다.
반복 : 리플렉션은 인터페이스 값에서 리플렉션 오브젝트로 되고 다시 반대로
됩니다.
3. 리플렉션 오브젝트를 수정하려면 값은 설
정 가능할 수 있어야 합니다.
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // 에러: 패닉이 올 것 입니다.
// 패닉 : reflect.Value.SetFloat 비주소적인 값을 이용
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println(“settability of v:”, v.CanSet())
// settability of v: false
“settability”는 무엇인가?
settability는 리플렉션 객체가 원래 항목을 가
지고 있는 것에 따라 결정됩니다.
var x float64 = 3.4
// 우리는 여기에서 x이 복사본을 넘겨주고 있습니다.
v := reflect.ValueOf(x)
// f(x) 와 f(&x)의 다른점에 대하여 생각합니다.
// v.SetFloat(7.1) 내부의 리플렉션 값 복사된 값으로 변경됩니다.
그럼, 어떻게 리플렉션 값을 수정할 수 있을까요?
“포인터를 사용합니다, Luke”
var x float64 = 3.4
	 p := reflect.ValueOf(&x) // x 주소를 가져온다.
	 fmt.Println("type of p:", p.Type()) // type of p: *float64
	 fmt.Println("settability of p:", p.CanSet()) // settable of p: false
	 v := p.Elem()
	 fmt.Println(" vvvv ", v)
	 fmt.Println("settable of v:", v.CanSet())
	 v.SetFloat(7.1)
	 fmt.Println(v.Interface()) // 7.1
	 fmt.Println(x) //7.1

Reflect package 사용하기

  • 1.
    reflect package in golang 문용준(myjlms99@gmail.com)
  • 2.
    리터럴 관리 기준 Type Value “harrypotter” 33 int 33 Type Value string harry potter 프로그램 언어들에는 리터럴 즉 값을 데이터 타입별로 관리한다.
  • 3.
    변수 정의 Type Value var sstring s = “harry potter” var x int x = 33 int x Type Value string harry potter 변수 33 변수는 데이터 타입을로 정의하고 값을 저장하는 장소를 가진다. s변수
  • 4.
    reflection 이란 var xint x = 33 Type Value int x변수 33 프로그램언어에서 reflection은 변수가 가진 데이터 타입을 인식하 여 타입 캐스팅 등의 요건을 처리하는 구조 변수 x 의 타입을 처리reflect.TypeOf(x) reflect.ValueOf(x) 변수 x 의 Value값에 대한 타입을 처리 reflect.ValueOf(x).Int() 변수 x 의 Value에 대한 실제 값을처리
  • 5.
    interface{}란 var all_type interface{} varxi int var xs string var xf float32 go lang에서 다른 데이터타입을 받아서 처리할 수 있는 데이터구조 all_type = xi fmt.Println(" int ", reflect.TypeOf(all_type)) all_type = xs fmt.Println(" string ", reflect.TypeOf(all_type)) all_type = xf fmt.Println(" float32 ", reflect.TypeOf(all_type))
  • 6.
    예제: interface정의 및구현(1/3) type Stringer interface { String() string } string을 처리하는 하나의 인터페이스 정의하고 타입을 정의하고 인 터페이스를 구현함 type Binary uint64 // Binary는 Stringer 인터페이스를 구현한다. func (i Binary) String() string { return strconv.Itoa(i.Get()) } //int 타입으로 변화 func (i Binary) Get() int { return int(i) }
  • 7.
    예제: interface정의 및구현(2/3) func ToString(any interface{}) string { switch vi := any.(type) { case uint64: return strconv.Itoa(int(vi)) case Binary: return strconv.Itoa(int(vi)) } return "error" } interface{}로 전달받아 처리하는 ToString함수를 정의
  • 8.
    예제: interface정의 및구현(3/3) ffunc main() { b := Binary(200) s := Stringer(b) var c interface{} = b // 여기서 b 복사본을 만든다. fmt.Println("string ", s.String()) fmt.Println(" bbbb", b) fmt.Println("ccccc ", c) fmt.Println("bbbbb string ", b.String()) fmt.Println("To String ", ToString(c)) fmt.Println(" String ", s.String()) } 실제 실행해조면 동일 한 값을 출력한다
  • 9.
    itable: 인터페이스 테이블 b에 값을 넣고 b를 s에 인터페이스를 넣는다. 인테페이스 구조는 인터페이스 내의 데이터 타입과 실질적인 데이 터 값을 저장하는 구조로 관리된다. 정의 메소드등이 있으면 인터페이스 itable에 메소드도 관리한다.
  • 10.
    itable 컴퓨팅 가능한 모든itable을 전부 미리 구성하는 것이 아닙니다. 구 조를 만들면 실제 런타임에 실행하면서 처리합니다. 컴파일러는 각 타입에 대한 타입 구조 생성 컴파일러는 각 타입에 대한 메소드 구조 생성 런타임시 itable을 검색하여 메소드를 실행
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
    Rob Pike의 리플렉션법칙들 http://blog.golang/laws-of-reflection reflect.TypeOf(interface {}) Type, reflect.ValueOf(interface{}) Value 1. 리플렉션은 인터페이스 값에서 리플렉션 오브젝트로 됩니다. 2. 리플렉션은 리플렉션 오브젝트에서 인터페이스 값으로 됩니다. 3. 리플렉션 오브텍드를 수정하려면 값은 설정할 수 있어야 됩니다. canSet( ) bool => true 일 경우만 갱신
  • 16.
    1. 리플렉션은 인터페이스값에서 리플렉션 오브젝트로 됩니다. var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println(“type:”, v.Type()) fmt.Println(“kind is float64:”, v.Kind() == reflect.Float64) fmt.Println(“value:”, v.Float()) //결과 type: float64 kind is float64: true value: 3.4
  • 17.
    유형(Type) 과 유형(Kind) varx unit8 = ‘x’ v := reflect.ValueOf(x) fmt.Println(“type:”, v.Type()) // unit8. fmt.Print(“kind is unit8: ”,v.Kind() == reflect.Unit8) // true. x = unit8(v.Unit()) // v.Unit returns a unit64. type MyInt int var x MyInt = 7 v := reflect.ValueOf(x) fmt.Println(“kind is Int: ”, v.Kind() == reflect.Int) // true
  • 18.
    2. 리플렉션은 리플렉션객체에서 인터페이 스 값으로 됩니다. // Interface는 interface{} 처럼 v 값을 반환한다. // func (v value) Interface() interface{} y := v.Interface().(float64) // y는 float64 타입을 가질 것이다. fmt.Println(y) fmt.Printf(“value is %7.1en”, v.Interface()) // 3.4e+00 즉, 인터페이스 메소드는 ValueOf 함수의반대입니다. 그결과는 정적 타입 interface{} 입니다. 반복 : 리플렉션은 인터페이스 값에서 리플렉션 오브젝트로 되고 다시 반대로 됩니다.
  • 19.
    3. 리플렉션 오브젝트를수정하려면 값은 설 정 가능할 수 있어야 합니다. var x float64 = 3.4 v := reflect.ValueOf(x) v.SetFloat(7.1) // 에러: 패닉이 올 것 입니다. // 패닉 : reflect.Value.SetFloat 비주소적인 값을 이용 var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println(“settability of v:”, v.CanSet()) // settability of v: false “settability”는 무엇인가?
  • 20.
    settability는 리플렉션 객체가원래 항목을 가 지고 있는 것에 따라 결정됩니다. var x float64 = 3.4 // 우리는 여기에서 x이 복사본을 넘겨주고 있습니다. v := reflect.ValueOf(x) // f(x) 와 f(&x)의 다른점에 대하여 생각합니다. // v.SetFloat(7.1) 내부의 리플렉션 값 복사된 값으로 변경됩니다. 그럼, 어떻게 리플렉션 값을 수정할 수 있을까요?
  • 21.
    “포인터를 사용합니다, Luke” varx float64 = 3.4 p := reflect.ValueOf(&x) // x 주소를 가져온다. fmt.Println("type of p:", p.Type()) // type of p: *float64 fmt.Println("settability of p:", p.CanSet()) // settable of p: false v := p.Elem() fmt.Println(" vvvv ", v) fmt.Println("settable of v:", v.CanSet()) v.SetFloat(7.1) fmt.Println(v.Interface()) // 7.1 fmt.Println(x) //7.1