2. 리터럴 관리 기준
Type
Value
“harry potter”
33 int
33
Type
Value
string
harry potter
프로그램 언어들에는 리터럴 즉 값을 데이터 타입별로 관리한다.
3. 변수 정의
Type
Value
var s string
s = “harry potter”
var x int
x = 33 int
x
Type
Value
string
harry potter
변수
33
변수는 데이터 타입을로 정의하고 값을 저장하는 장소를 가진다.
s변수
4. 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에 대한 실제 값을처리
5. 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))
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을 검색하여 메소드를 실행
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)
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
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”
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