일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 이맥스
- 스플릿키보드
- Go 언어
- 키보드
- magicsculpt
- 다이어트
- 엘리스배열
- mopria
- 터미널
- Golang
- md600alpha
- mf642cdw
- 바로코
- 음각몰드
- Go
- 건프라
- 리플렉션
- 양자역학
- 패널라인
- nil
- 프라파손
- Griffiths
- mistel md600 alpha
- emacs
- Reflection
- driverless
- go언어
- 고양이책
- 체리적축저소음
- 벤치마크
- Today
- Total
Meandering Trajectory
Go: 리플렉션 #2 본문
이전 포스팅에서 리플렉션에 대한 아주 간략한 1 설명을 했다. 이번 글에서는 간단한 예제 코드를 통해 리플렉션이 어떻게 유용한지 알아보도록 하자.
1 import "reflect"
2
3 var methodMap map[string]reflect.Method
4
5 func initMethodMap(i interface{}) {
6 methodMap = make(map[string]reflect.Method)
7
8 t := reflect.TypeOf(i)
9 for idx := 0; idx < t.NumMethod(); idx++ {
10 m := t.Method(idx)
11 methodMap[m.Name] = m
12 }
13 }
initMethodMap 함수는 임의의 구조체 변수를 입력 파라미터로 받은 뒤 8번째 줄에서 구조체 변수의 리플렉션 타입(reflect.Type 형)을 얻는다. 9번째 줄의 for문에는 t.NumMethod(i)와 같이 리플렉션 타입의 NumMethod 메서드를 호출한 부분이 있는데 이 메서드는 t가 가르키는 타입에 구현된 메서스의 수를 반환한다. 그리고 10번째 줄에서는 t.Method(idx)를 이용해 t가 가르키는 타입에 구현된 idx번째 메서드 값(reflect.Value 타입)를 얻는다. 그리고 마지막으로 11번째 쭐에서는 해당 메서드의 이름(m.Name)을 키로 methodMap에 메서드 값을 할당한다.
간단히 말해서 위 코드에 있는 initMethodMap 함수는 임의의 구조체 변수를 입력 파라미터로 받은 뒤 해당 변수가 가르키는 구조체에 구현된 모든 메서드가 들어있는 맵(methodMap)을 만드는 함수다. 코드에 나온데로 key는 메서드 이름이다.
아래와 같은 코드를 이용하면 맵에 저장된 메서드 호출할 수 있다.
in := []reflect.Value{reflect.ValueOf(r)} // r은 A메서드를 구현한 타입의 오브젝트
methodMap["A"].Func.Call(in)
이름이 A고 입력 파라미터가 없는 메서드를 호출하는 예다. 그런데 이 코드 첫번째 줄을 보면 이상한 점 하나가 눈에 띈다. 분명히 입력 파라미터가 없는 메서드를 호출하는 코드라고 했는데 입력 파라미터를 하나를 in이라는 배열에 담는 코드가 있다. 이렇게 코드를 작성해야 하는 이유는 Go 리플렉션을 통해 메서드를 호출하는 경우 항상 해당 메서드에 대응되는 구조체 변수를 첫번째 파라미터로 주어야 하기 때문이다. 2
이와 같은 맵을 이용하면 텍스트 파일이나 JSON 메시지 같은 것을 통해 메서드 이름을 받아서 메서드를 호출하는 프로그램을 작성하기가 용이하다. 텍스트나 JSON 메시지를 파싱해서 호출할 메서드 이름을 얻은 뒤 함수를 호출하는 부분만 작성하고 나면 새로운 메서드가 추가되더라도 호출하는 부분의 코드는 변경할 필요가 없다는 장점이 있다.
만약 리플렉션이 없다면 호출하는 부분은 case 문같은 것으로 대체될테고 새로운 메서드가 추가될 때마다 case 문을 수정해야 되는 번거로움이 생긴다.
'컴퓨터 > GoLang' 카테고리의 다른 글
아니 Go의 상태가… (0) | 2017.08.12 |
---|---|
Go 채널 (0) | 2017.08.09 |
Go: 리플렉션 #1 (0) | 2017.07.15 |
Go 언어 - 벤치마크 (0) | 2017.07.08 |
Go 패키지의 정체 (0) | 2017.06.29 |