LoginSignup
2
1

More than 3 years have passed since last update.

Golang 基礎 (環境構築など) part1

Last updated at Posted at 2020-08-10

前準備や基本情報

パッケージ管理

ターミナルで実行。go.modファイルが作成される。

go mod init github.com/${GITHUB_USER}/${PROJECT_NAME}

あとは go get するだけ。

実行環境(docker)

main.goがあるディレクトリに以下を置く。(go.sumは1回でもgo getしてる場合のみCOPYする)

Dockerfile
FROM golang:alpine

WORKDIR /go/src/app

COPY go.mod .
# COPY go.sum . 
RUN go mod download

COPY . .
docker-compose.yml
version: "3.7"

services:
  goapp:
    build: .
    tty: true
    volumes:
    - .:/go/src/app

以下のコマンドでコンテナの中に入る。(goappはサービス名)

~% docker-compose up -d
~% docker-compose exec goapp /bin/ash

コンテナ内でmain.goを実行。

/go/src/app # go run main.go

publicとprivate

  • 命名規則で判別。(変数名、関数名など)そのため、基本的にキャピタルケースorパスカルケースで命名する。
    • public: 他のパッケージからでも呼び出せる。先頭を大文字にする!
    • private: パッケージ内でのみ呼び出せる。先頭は小文字。
var PublicVariable string = "Public" // 呼び出せる
var privateVariable string = "private" // 呼び出せない
  • ファイル名はスネークケース ex. line_api.go

基礎文法

strconv パッケージ

string型と基本的なデータ型との間の変換をするパッケージ

i, err := strconv.Atoi("-42") // stringからintへ
s := strconv.Itoa(-42)  // intからstringへ

スライスのmakeとcap

cap: メモリに確保してる分

m := make([]int, 5)
n := make([]int, 0, 5)
fmt.Printf("len=%d cap=%d value=%v\n", len(m), cap(m), m) // len=5 cap=5 value=[0 0 0 0 0]
fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) // len=0 cap=5 value=[]
s1 := make([]int, 0) // 空のスライスをメモリに確保する(mapも同様)
var s2 []int // nil(メモリに確保しない。mapも同様)

スライスは配列への参照のようなもの

スライスはどんなデータも格納しておらず、単に元の配列の部分列を指し示しています。
スライスの要素を変更すると、その元となる配列の対応する要素が変更されます。
同じ元となる配列を共有している他のスライスは、それらの変更が反映されます。

names := [4]string{
    "John",
    "Paul",
    "George",
    "Ringo",
}
fmt.Println(names)  // [John Paul George Ringo]

a := names[0:2]
b := names[1:3]
fmt.Println(a, b)  // [John Paul] [Paul George]

b[0] = "XXX"
fmt.Println(a, b)  // [John XXX] [XXX George]
fmt.Println(names)  // [John XXX George Ringo]

map(辞書型)

m := map[string]int{"apple": 100, "banana": 200}
fmt.Println(m["nothing"]) // 0

m["orange"] = 300    // 要素の追加
delete(m, "orange")  // 削除

v, ok := m["apple"] // 2つ目の返り値は受け取らなくてもおっけい
fmt.Println(v, ok) // 100 true

可変長引数

func foo(params ...int) {
    fmt.Printf("len=%d params=%v\n" , len(params), params)
    for _, param := range params {
        fmt.Println(param)
    }
}
func main() {
    foo() // len=0 params=[]
    foo(1, 2) // len=2 params=[1 2]

    s := []int{1, 2, 3}
    foo(s...) // len=3 params=[1 2 3]
}

forとrange

// 条件のみ
sum := 1
for sum < 500 {
    sum += sum
}
fmt.Println(sum)

// 無限ループ
for {
    fmt.Println("hello")
}

// range
l := []string{"python", "go", "java"}
for index, value := range l{
    fmt.Println(index, value)
}

m := map[string]int{"apple": 100, "banan": 200}
for key, value := range m{
    fmt.Println(key, value)
}
for key := range m{
    fmt.Println(key)
}
for _, value := range m{
    fmt.Println(value)
}

swicth

switch caseは、上から下へcaseを評価します。 caseの条件が一致すれば、そこで停止(自動的にbreak)します。

// 通常
os := "mac"
switch os {
case "windows":
    fmt.Println("windows!!")
case "mac":
    fmt.Println("mac!!")
default:
    fmt.Println("linux!!")
}
// 条件省略
t := time.Now()
switch {
case t.Hour() < 12:
    fmt.Println("morning")
case t.Hour() < 17:
    fmt.Println("afternoon")
default:
    fmt.Println("foooo")
}

panicとrecover

panicで強制終了してしまう処理の前にdeferでrecover()すると強制終了しなくなる!

func thirdPartyConnectDB() {
    panic("Unable to connect database.")
}

func save() {
    defer func() {
        s := recover()
        fmt.Println(s)
    }()
    thirdPartyConnectDB()
}

func main() {
    save()
    fmt.Println("ok?")
}

参考

現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
https://xblood.hatenablog.com/entry/2019/01/28/213223

part2

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1