Golang basic: Difference between revisions
No edit summary |
No edit summary |
||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Overview == | == Overview == | ||
Golang basic 내용 정리 | Golang basic 내용 정리 | ||
== select == | |||
The select statement is used to choose from multiple send/receive channel operations. The select statement blocks until one of the send/receive operation is ready. | |||
If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed. | |||
<source lang=go> | |||
package main | |||
import ( | |||
"context" | |||
"fmt" | |||
"time" | |||
) | |||
func main() { | |||
fmt.Println("Clear is better than clever.") | |||
ctx, canceled := context.WithCancel(context.Background()) | |||
canceled() | |||
t := time.NewTicker(1 * time.Second) | |||
out := make(chan int, 1) | |||
select { | |||
case <-ctx.Done(): | |||
fmt.Println("nope: canceled context selected") | |||
case out <- work(): | |||
fmt.Println("work selected") | |||
case <-t.C: | |||
fmt.Println("ticker selected") | |||
} | |||
} | |||
func work() int { | |||
time.Sleep(10 * time.Second) | |||
fmt.Printf("work work %#v\n", time.Now()) | |||
return 1 | |||
} | |||
</source> | |||
== Values == | == Values == | ||
Line 102: | Line 140: | ||
/usr/local/go/src/runtime/mfinal.go:156 +0x61 | /usr/local/go/src/runtime/mfinal.go:156 +0x61 | ||
Aborted (core dumped) | Aborted (core dumped) | ||
</pre> | |||
== Marshal/Unmarshal == | |||
<source lang=go> | |||
package main | |||
import ( | |||
"encoding/json" | |||
"fmt" | |||
"log" | |||
) | |||
const input = ` | |||
{ | |||
"type": "sound", | |||
"msg": { | |||
"description": "dynamite", | |||
"authority": "the Bruce Dickinson" | |||
} | |||
} | |||
` | |||
type Envelope struct { | |||
Type string | |||
Msg interface{} | |||
} | |||
type Sound struct { | |||
Description string | |||
Authority string | |||
} | |||
func main() { | |||
var msg json.RawMessage | |||
env := Envelope{ | |||
Msg: &msg, | |||
} | |||
if err := json.Unmarshal([]byte(input), &env); err != nil { | |||
log.Fatal(err) | |||
} | |||
switch env.Type { | |||
case "sound": | |||
var s Sound | |||
if err := json.Unmarshal(msg, &s); err != nil { | |||
log.Fatal(err) | |||
} | |||
var desc string = s.Description | |||
fmt.Println(desc) | |||
default: | |||
log.Fatalf("unknown message type: %q", env.Type) | |||
} | |||
} | |||
</source> | |||
* https://eagain.net/articles/go-dynamic-json/ | |||
== Errors == | |||
=== go get private repository return error === | |||
go build 를 하던 도중 다음과 같은 에러를 만났다. 원인은 필요 패키지 중 하나가 private repository 에 있었기 때문이었다. | |||
<pre> | |||
gitlab.com/voipbin/bin-manager/common-handler.git/pkg/rabbitmqhandler: gitlab.com/voipbin/bin-manager/common-handler.git@v0.0.0-20210201031332-de387a37fc1c: verifying module: gitlab.com/voipbin/bin-manager/common-handler.git@v0.0.0-20210201031332-de387a37fc1c: reading https://sum.golang.org/lookup/gitlab.com/voipbin/bin-manager/common-handler.git@v0.0.0-20210201031332-de387a37fc1c: 410 Gone | |||
</pre> | |||
다음과 같은 환경변수를 추가 후, 정상작동을 확인했다. | |||
<pre> | |||
$ export GOPRIVATE="gitlab.com/voipbin" | |||
</pre> | </pre> | ||
Latest revision as of 04:22, 1 February 2021
Overview
Golang basic 내용 정리
select
The select statement is used to choose from multiple send/receive channel operations. The select statement blocks until one of the send/receive operation is ready.
If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed. <source lang=go> package main
import ( "context" "fmt" "time" )
func main() { fmt.Println("Clear is better than clever.") ctx, canceled := context.WithCancel(context.Background()) canceled()
t := time.NewTicker(1 * time.Second)
out := make(chan int, 1) select { case <-ctx.Done(): fmt.Println("nope: canceled context selected") case out <- work(): fmt.Println("work selected") case <-t.C: fmt.Println("ticker selected") } }
func work() int { time.Sleep(10 * time.Second) fmt.Printf("work work %#v\n", time.Now()) return 1 } </source>
Values
Variables
var 키워드를 이용해서 선언한다. var 키워드 뒤에 변수명을 적고, 그 뒤에 변수타입을 적는다. 다음은 정수(int) 타입의 변수 a 를 선언한 것이다. <source lang=go> var a int </source>
변수 선언문에서 변수 초기값을 할당할 수도 있다. 즉, float32 타입에 초기값을 입력하고자 한다면 다음과 같이 하면 된다. <source lang=go> var b float32 = 12.3 </source>
일단 선언된 변수는 해당 타입의 값을 할당할 수 있다. <source lang=go> a = 10 b = 1.23 </source>
만약 선언된 변수가 Go 프로그램에서 사용되지 않는다면, 에러를 발생시킨다. 따라서 사용되지 않는 변수는 프로그램에서 삭제해야 한다.
$ go build ./main.go # command-line-arguments ./main.go:22:7: k declared and not used
동일한 타입의 변수가 여러 개 있을 경우, 변수들을 나열하고 마지막에 타입을 한번만 지정할 수 있다. <source lang=go> var i, j, k int = 1, 2, 3 </source>
변수를 선언하면서 초기값을 지정하지 않으면, Go 는 zero-value 를 기본적으로 할당한다. 숫자형에는 0, bool 타입에는 false, string 타입에는 ""(빈 문자열)을 할당한다.
Go 에서는 할당되는 값을 보고 그 타입을 추론하는 기능이 자주 사용된다.
아래의 예제에서는 i 에는 int, s 에는 string 타입이 자동으로 할당된다. <source lang=go> var i = 1 var s = "hi" </source>
Debug
GOTRACEBACK
환경변수에 GOTRACEBACK=crash 를 지정해놓으면, 문제 발생시 core dump 를 출력한다.
$ ./main panic: duplicate metrics collector registration attempted goroutine 1 [running]: panic(0x80b2a0, 0xc00000d040) /usr/local/go/src/runtime/panic.go:556 +0x2cb fp=0xc0000dbe38 sp=0xc0000dbda8 pc=0x42c95b github.com/prometheus/client_golang/prometheus.(*Registry).MustRegister(0xc0000a04b0, 0xc000083050, 0x1, 0x1) /home/sungtaekim/go/src/github.com/prometheus/client_golang/prometheus/registry.go:391 +0xad fp=0xc0000dbe80 sp=0xc0000dbe38 pc=0x75cb9d github.com/prometheus/client_golang/prometheus.MustRegister(0xc000083050, 0x1, 0x1) /home/sungtaekim/go/src/github.com/prometheus/client_golang/prometheus/registry.go:176 +0x53 fp=0xc0000dbeb0 sp=0xc0000dbe80 pc=0x75b883 github.com/prometheus/client_golang/prometheus/promauto.NewCounter(0x0, 0x0, 0x0, 0x0, 0xc00008a270, 0x27, 0x861b42, 0x1f, 0x0, 0x8c80e0, ...) /home/sungtaekim/go/src/github.com/prometheus/client_golang/prometheus/promauto/auto.go:136 +0xf2 fp=0xc0000dbf30 sp=0xc0000dbeb0 pc=0x7670c2 main.init() /home/sungtaekim/worksapce/asterisk_exporter/main.go:106 +0xa55 fp=0xc0000dbf98 sp=0xc0000dbf30 pc=0x77cd35 runtime.main() /usr/local/go/src/runtime/proc.go:189 +0x1bd fp=0xc0000dbfe0 sp=0xc0000dbf98 pc=0x42e63d runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000dbfe8 sp=0xc0000dbfe0 pc=0x4591d1 goroutine 2 [force gc (idle)]: runtime.gopark(0x872f90, 0xb98140, 0x1410, 0x1) /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc00003ef80 sp=0xc00003ef60 pc=0x42ea7b runtime.goparkunlock(0xb98140, 0x1410, 0x1) /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc00003efb0 sp=0xc00003ef80 pc=0x42eb23 runtime.forcegchelper() /usr/local/go/src/runtime/proc.go:251 +0xb3 fp=0xc00003efe0 sp=0xc00003efb0 pc=0x42e8f3 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc00003efe8 sp=0xc00003efe0 pc=0x4591d1 created by runtime.init.4 /usr/local/go/src/runtime/proc.go:240 +0x35 goroutine 3 [GC sweep wait]: runtime.gopark(0x872f90, 0xb983c0, 0x42140c, 0x1) /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc00003f780 sp=0xc00003f760 pc=0x42ea7b runtime.goparkunlock(0xb983c0, 0x8b140c, 0x1) /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc00003f7b0 sp=0xc00003f780 pc=0x42eb23 runtime.bgsweep(0xc000066000) /usr/local/go/src/runtime/mgcsweep.go:52 +0x8f fp=0xc00003f7d8 sp=0xc00003f7b0 pc=0x4213bf runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc00003f7e0 sp=0xc00003f7d8 pc=0x4591d1 created by runtime.gcenable /usr/local/go/src/runtime/mgc.go:216 +0x58 goroutine 18 [finalizer wait]: runtime.gopark(0x872f90, 0xbb6048, 0x20000140f, 0x1) /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc00003e728 sp=0xc00003e708 pc=0x42ea7b runtime.goparkunlock(0xbb6048, 0x40140f, 0x1) /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc00003e758 sp=0xc00003e728 pc=0x42eb23 runtime.runfinq() /usr/local/go/src/runtime/mfinal.go:175 +0x99 fp=0xc00003e7e0 sp=0xc00003e758 pc=0x418d99 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc00003e7e8 sp=0xc00003e7e0 pc=0x4591d1 created by runtime.createfing /usr/local/go/src/runtime/mfinal.go:156 +0x61 Aborted (core dumped)
Marshal/Unmarshal
<source lang=go> package main
import ( "encoding/json" "fmt" "log" )
const input = ` { "type": "sound", "msg": { "description": "dynamite", "authority": "the Bruce Dickinson" } } `
type Envelope struct { Type string Msg interface{} }
type Sound struct { Description string Authority string }
func main() { var msg json.RawMessage env := Envelope{ Msg: &msg, } if err := json.Unmarshal([]byte(input), &env); err != nil { log.Fatal(err) } switch env.Type { case "sound": var s Sound if err := json.Unmarshal(msg, &s); err != nil { log.Fatal(err) } var desc string = s.Description fmt.Println(desc) default: log.Fatalf("unknown message type: %q", env.Type) } } </source>
Errors
go get private repository return error
go build 를 하던 도중 다음과 같은 에러를 만났다. 원인은 필요 패키지 중 하나가 private repository 에 있었기 때문이었다.
gitlab.com/voipbin/bin-manager/common-handler.git/pkg/rabbitmqhandler: gitlab.com/voipbin/bin-manager/common-handler.git@v0.0.0-20210201031332-de387a37fc1c: verifying module: gitlab.com/voipbin/bin-manager/common-handler.git@v0.0.0-20210201031332-de387a37fc1c: reading https://sum.golang.org/lookup/gitlab.com/voipbin/bin-manager/common-handler.git@v0.0.0-20210201031332-de387a37fc1c: 410 Gone
다음과 같은 환경변수를 추가 후, 정상작동을 확인했다.
$ export GOPRIVATE="gitlab.com/voipbin"
Reference
- http://golang.site - 예제로 배우는 Go 프로그래밍