최근에 바뀐 go 언어 프로그래밍의 습관, 나름대로의 규칙들.
By SeukWon Kang
나름대로는 go 언어를 꽤 많이 쓴 편이라고 생각하고 있었습니다만
( go4game, goguelike 둘다 코드의 양도 있는 편이고 사용하는 기능도 tcp/ip, http, client, websocket 등 꽤 다양하게 사용합니다. )
최근에 google/gxui 코드를 보면서 이런저런 것들을 많이 생각하게 되었습니다.
https://github.com/google/gxui
그 여파로 goguelike2에 이런 저런 refactoring을 시도 하게 되었는데.
그 중 적어 볼만한 것들을 적어 봅니다. (이 것이 정답이라고 말할수는 없겠지만 )
1. private interface , public interface
전에 interface에 대해 적은 적이 있는데
(http://kasw.blogspot.kr/2015/02/go-interface.html)
이후로 약간 생각이 바뀐 것이
큰 규모의 프로젝트에서는 (중규모이상의)주요 모듈 단위로 shared public interface package를 만드는 것입니다.
여전히 package 내에서만 사용할 interface는 private로 만들어 쓰는 것이 좋지만 그렇게 해결 할 수 없는 경우도 있고 그 경우에는 C/C++ 의 header 처럼 공용 interface를 선언해서 사용합니다.
아직 결론을 내리지 못하고 있는 것은 이것을 각각 독립 package로 만드는 것이 좋을지 아니면 적당한 규모로 묶어서 ( logical module 단위 ) 공용으로 만드는 것이 좋을지 입니다.
현재 goguelike2에서는 후자 를 사용하고 있습니다.
예를 들면 terrain을 담당하는 공용 interface package 와 server를 담당하는 interface package 를 분리 하고 있습니다.
server interface package는 10여개 정도의 struct 에 대한 interface가 정의 되어 있지요.
2. interface naming
저는 interface naming을 implementation struct + I 형태로 하고 있습니다.
예를 들어 Terrain struct가 있다면 이 terrain 의 interface는 TerrainI 가 되는 식 입니다.
여러 개의 구현 형태가 있다면 idpos 에서 그랬듯이 구현 struct 뒤에 postfix를 붙입니다.
그래서
IdPosI 가 2차원 평면상의 object의 위치를 관리해주는 interface라면
- IdPos1M : 1차원 map 구현
- IdPos2M : 2 차원 map 구현 ( map 의 map 형태 )
- IdPos1S : 1차원 slice 구현
- IdPos2S : 2차원 slice 구현
이런 식이지요.
전에도 적었듯이 go 언어에서 권장하는 interface naming은 -er을 붙이는 것입니다만 영어 실력이 딸려서 적당한 이름을 찾을 수 없는 관계로 저렇게 하고 있습니다.
3. typed const
const를 정의할때 아래처럼 type 을 정의하고 그 type으로 선언 하는 것입니다.
처음에는 type없이 그냥 쓰곤 했는데 type check을 통해서 error를 줄일수 있을것 같아서 이런 형태로 바꾸었습니다. 물론 arithmetic 연산이 필요한 const의 경우는 이런식으로 만들지 않습니다. != 과 == 정도만이 필요한 경우 이런 식으로 typed enumeration을 흉내 내는 것이지요.
//start
type EqPos_Type uint8
const (
EqType_Head = EqPos_Type(iota)
EqType_Neck
EqType_Ring
EqType_Belt
EqType_Foot
EqType_Body
EqType_Hand
EqType_Ear
EqType_End
EqType_Inven = EqType_End
)
//end
이 글(http://kasw.blogspot.kr/2015/05/go-2.html)로 이어집니다.