- go로 개발하면서 유용하게 써먹을 수 있는 Tip, 정보들을 정리한다
slice 중 마지막 index만 제거하고 싶다면 : 연산자 사용하기
if len(slice) > 0 {
slice = slice[:len(slice)-1]
}
...
// :사이즈로 세팅하면 원하는 개수만큼만 리턴 또는 slice를 생성해 줄 수 있다
return result[:size]
mulitple argument를 받고 싶다면 ... 사용하기
func repeatMe(txt ...string) {
fmt.Println(txt)
}
func main() {
repeatMe("a", "b", "c", "d", "e")
// [a b c d e]
}
struct를 리턴할 땐 포인터를 사용하는게 좋다
- struct를 생성하고 리턴할때도 새로운 object로 복사가 되기 때문에 앱을 가볍게 만들려면 포인터로, 주소를 리턴하여 활용하는 것이 효율적
func NewAccount(owner string) *Account {
account := Account{owner: owner}
return &account
}
클로저에서 go 루틴 사용 시 반복문 주의
- 반복문 내 클로저 go 루틴 사용시, 반복문의 변수를 그대로 넣으면 go 루틴에선 각각 다른 값이 아닌 동일한 변수로 받아들여지기 때문에 원하는 데이터를 확인하지 못할 수 있다
타이머를 만들려면 time.After 보단 delay를 써라
- 타이머 기능이 필요하여 time 패키지를 쓰는 경우가 있는데, 아래와 같이 사용하게 되면 Memory Leak이 발생하게 된다
select {
case <-time.After(time.Second):
// 초마다 확인
case <-ctx.Done():
// Context가 종료될 경우 확인
// 위 time보다 먼저 실행되면 Context는 종료되어도 타이머는 종료되지 않아 Memory Leak 발생
}
- 그래서 time.After 보단 delay를 쓰면 GC로 인해 불필요한 메모리를 정리할 수 있게 된다
delay := time.NewTimer(time.Second)
select {
case <-delay.C:
// 초마다 확인
case <-ctx.Done():
// Context 종료 또는 타이머가 종료될 때 확인
if !delay.Stop() {
// Context 종료 직후 타이머가 만료될 경우, 만료인지 중지인지 체크
<-delay.C
}
}
코드를 그래프로 나타내고 싶다면 go-callvis 라이브러리를 써봐라
go-callvis ./