#author("2020-01-03T09:23:57+00:00","","")
#mynavi()
#setlinebreak(on)

* 目次 [#j4af1b33]
#contents
- 参照
-- https://golang.org/doc/  (公式ドキュメント)
-- https://github.com/golang/go
- 関連
-- [[Goルーチンで並列HTTPリクエストを発行]]
-- [[AWS SDK for Go を使ってみる]]
-- [[Goルーチン]]

* Go言語とは [#g7f68402]
#html(<div class="pl10">)
Go言語はGoogleによって開発されているプログラミング言語で Linux、Mac、Window 等の主要OS 及び Android、iOS上でも動作する。(2016年現在)
※ Google App Engine でもサポートされている。
#html(</div>)

* インストール [#n5409608]
#html(<div class="pl10">)

https://golang.org/doc/install#install

** Mac の場合 [#s0ed9876]
#html(<div class="pl10">)
Homebrew でのインストールが可能
#myterm2(){{
brew install go
}}
※パッケージを落としてインストールする場合は https://golang.org/dl/ から取得
#html(</div>)

インストール時に言われた通りにPATHを通す。
$HOME/.bash_profile
#myterm2(){{
export GOPATH=/usr/local/opt/go/libexec
export PATH=$PATH:$GOPATH/bin
}}

#html(</div>)

* Hello World [#f5d79ee5]
#html(<div class="pl10">)
hello.go
#mycode2(){{
package main

import "fmt"

func main() {
  fmt.Printf("Hello, World\n")
}
}}

実行
#myterm2(){{
go run hello.go
}}
#html(</div>)

* 環境変数 [#l125530b]
#html(<div class="pl10">)

| 環境変数 | 説明 |h
| GOROOT |  開発ツールのインストールPATH |
| GOPATH |  ワークディレクトリのPATH |
| GOOS | ビルドした実行ファイルを実行させるOS |
| GOARCH | ビルドした実行ファイルが実行可能なアーキテクチャ |

#html(</div>)

* 基本的な構文など [#jed80257]
#html(<div class="pl10">)

#TODO

** パッケージ [#c9143e5f]
#html(<div class="pl10">)

- 自身のパッケージは package で宣言する。
- 利用するパッケージは import で宣言する。
- main以外のパッケージと格納ディレクイトリは同じ名前にする。(慣例)

#mycode2(){{
package main

import "fmt"

func main(){
    fmt.Println("Hello World")
}
}}

複数 import は以下のように記述する事も可能
#mycode2(){{
    :
import (
    "fmt"
    "encoding/json"
)
    :
}}


#html(</div>)

** 変数 [#t05f93f0]
#html(<div class="pl10">)

- 変数は var で宣言する。
- 初期値を指定した場合は型指定は省略できる。
- ローカルスコープの変数に限り、「変数名:= 式」で宣言する事も可能。(型宣言は指定不可)

#mycode2(){{
// aを宣言
var a int

// 初期値を指定してbを宣言
var b int = 1

// 初期値を指定してcを宣言(型指定を省略)
var c = 0

// 複数の変数を宣言
var d1, d2 int
var e1, e2 int = 1, 2
var f1, f2 = 1, 2

// ローカル変数の宣言例
func main(){

    // aを宣言
    var a int
    a = 1

    // bの宣言と初期化(型指定は不可)
    b := 1
}
}}

#html(</div>)

** 定数 [#s07e7f3c]
#html(<div class="pl10">)

定数は const キーワードで宣言する。
#mycode2(){{
package main

import "fmt"

const c1 string = "const1"

func main(){

    const c2 string = "const2"

    fmt.Printf("c1: %s\n", c1) 
    fmt.Printf("c2: %s\n", c2) 
}
}}

#html(</div>)


** データ型 [#m516f8ea]
#html(<div class="pl10">)
#TODO
#TODO(数値)
#TODO(文字列)
#TODO([]byte)
#TODO([]rune)
#TODO(真偽値)
#TODO(配列/スライス)
#TODO(マップ)
#TODO(ポインタ)
#TODO(構造体)
#TODO(nil)
#html(</div>)


** 型宣言 [#v147f939]
#html(<div class="pl10">)

type を使用する事で、型に別名を付けて新しい型を作成する事ができる。

#mycode2(){{
package main

import "fmt"

type MyInt int 

type MyStruct struct {
    Id MyInt
    Name string
}

func main(){
    x := MyStruct{Id: 100, Name: "Taro"}
    fmt.Printf("Id: %d\n", x.Id)
    fmt.Printf("Name: %s\n", x.Name)
}
}}

#html(</div>)


** 条件分岐 [#r1e59357]
#html(<div class="pl10">)

*** if による条件分岐 [#x7fff487]
#html(<div class="pl10">)
#mycode2(){{
package main

import "fmt"

func main(){

    x := 3

    if x == 1 { 
        fmt.Println("x is 1")
    } else if x == 2 { 
        fmt.Println("x is 2")
    } else {
        fmt.Println("others")
    }   
}
}}
#html(</div>)

*** switch による条件分岐 [#ud1039bd]
#html(<div class="pl10">)

他の言語と同様に switch も使用できる。
ただし Java等と違って break を書く必要がない点が異なる。
逆に、次の case に遷移させたい場合は、fallthrough を使用する。

#mycode2(){{
package main

import "fmt"

func main(){

    x := 3

    switch x { 
    case 1:
      fmt.Println("x is 1")
    case 2:
      fmt.Println("x is 2")
    case 3:
      fmt.Println("x is 3")
      fallthrough
    default:
      // x = 3 の時だけここが実行される
      fmt.Println("others")
    }

    // 以下の書き方も可能
    switch {
    case x == 1:
      fmt.Println("x is 1")
    case x == 2:
      fmt.Println("x is 2")
    case x == 3:
      fmt.Println("x is 3")
    }
}
}}
#html(</div>)

#html(</div>)

** 繰り返し [#i8ffcf5f]
#html(<div class="pl10">)

繰り返しは全て for で行う。
while や foreach は存在しないが、同等の処理を for のみで行う事が可能となっている。

#mycode2(){{
package main

import "fmt"

func main(){

    // 通常のforループ
    for i := 0; i < 5; i++ {
        fmt.Printf("i = %d\n", i)
    }

    // 疑似while
    x := 0
    for x < 5 { 
        fmt.Printf("x = %d\n", x)
        x++
    }

    // 永久ループ
    y := 0
    for {
        fmt.Printf("y = %d\n", y)
        y++ 
        if y >= 5 { 
            break
        }
    }

    // 配列要素分繰り返し(疑似foreach)
    array1 := []int{1,2,3,4,5}
    for i, val := range array1 {
        fmt.Printf("val[%d] = %d\n", i,val)
    }

    // マップの要素分繰り返し(疑似foreach)
    m := map[string]int{"k1": 1, "k2": 2, "k3": 3, "k4": 4, "k5": 5}
    for key, val := range m { 
        fmt.Printf("val[%s] = %d\n", key,val)
    }
}
}}

#html(</div>)

** 関数 [#i345716b]
#html(<div class="pl10">)

- 関数は func で宣言する。
- 他のパッケージに公開する関数は、頭の1文字目を大文字にする。
- 複数の戻り値を返却する事も可能。
- 可変長引数を受け取る事も可能。
- 関数の終了処理を defer で定義する事ができる

#mycode2(){{
package main

import "fmt"

// 通常の関数
func myAdd(a int, b int) int{
    result := a + b 
    return result
}

// 他パッケージに公開する関数
func MyAdd(a int, b int) int {
    return myAdd(a, b)
}

// 戻り値が2つの関数
func multiResult() (int, int){
    return 1, 10
}

// 可変長引数を受け取る関数
func multiArgs(a string, args...string){

    // 関数の終了処理を defer で定義する事ができる
    defer func() {
        fmt.Println("multiArgs end!")
    }()

    fmt.Printf("a = %s\n", a)
    for i, val := range args {
        fmt.Printf("args[%d] = %s\n", i, val)
    }   
}


func main(){

    result := myAdd(1, 2)
    fmt.Printf("myAdd(1,2) = %d\n", result)

    x1, x2 := multiResult()
    fmt.Printf("multiResult() = %d, %d\n", x1, x2) 

    multiArgs("a", "b", "c", "d")
}
}}

#html(</div>)


**インターフェース [#p9191eb1]
#html(<div class="pl10">)
#TODO
#html(</div>)

** 例外処理 [#z50427ec]
#html(<div class="pl10">)
#TODO(panic と recover)
#html(</div>)

#html(</div>)

* ビルド [#ke012467]
#html(<div class="pl10">)
#TODO
#html(</div>)

* Goルーチン [#nec2b113]
#html(<div class="pl10">)
[[Goルーチン]] を参照
#html(</div>)

* ブラウザ上でGoのソースを実行可能な環境 [#lcbf9af8]
#html(<div class="pl10">)

Go Playground
https://play.golang.org

A Tour of Go
https://tour.golang.org

#html(</div>)

トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS