Golang入門編〜基礎文法/配列まで〜
前書き
今回はGolangの基礎文法についてまとめていきます。Golangとは静的型付け言語であり、C言語の伝統に基づいたコンパイラ言語です。その為PythonやJavaScriptなどのインタプリタ言語に加えると実行速度自体は速いとされています。JavaやC++のような静的型付けによるセキュリティの堅牢性やRubyやPythonのような可読性をいいどこ取りした言語のように感じます。一方で、Golang自体はモダンな言語とされていますが、一般的にシステムへの使用度は低く、JavaやRubyの方が国内では使用されています。Golangの由来自体はGoogleエンジニア により開発されたことが起因とされています。
文法基礎
まずはGolangに関する基礎文法をざっくり勉強していきます。今回はUdemyをベースにQiitaでおさらいしながら学習を進めました。
変数定義
ローカル変数とパッケージ変数(関数外部で定義された変数)の定義は以下のような感じです。
package main import "fmt" // パッケージ変数 var ( n int = 100 t float64 = 3.64 u8 uint8 = 255 i8 int8 = 127 f32 float32 = 0.2 c64 complex64 = -15+100i ) func main() { var a int = 50 // ローカル変数 k := 3.2 // 簡略化したローカル変数定義 n = n + a // パッケージ変数は参照可能 fmt.Printf("n=%d\n", n) fmt.Printf("%f\n", k) }
表示
const ( team_name = "buffaloes" co_name = "ORIX" ) func main(){ var k int8 = 4 fmt.Println("num------------") fmt.Printf("type=%T : value=%v\n", k, k) fmt.Println("const----------") fmt.Println(team_name, co_name) }
num------------ type=int8 : value=4 const---------- buffaloes ORIX
シフト
func main(){ fmt.Println("shift----------") fmt.Println(1 << 0) fmt.Println(1 << 1) fmt.Println(1 << 2) }
shift---------- 1 2 4
文字列変換
import ( "fmt" "strings" ) func main(){ fmt.Println("replace----------") var ss string = "Hello World" fmt.Println(strings.Replace(ss, "H", "O", 1)) }
Boolean
func main(){ fmt.Println("boolean----------") t, f := true, false fmt.Println(t || f) fmt.Println(t && f) fmt.Println(!f) }
boolean---------- true false true
Type(型)変換
func main(){ fmt.Println("retype----------") var x int = 1 xx := float32(x) fmt.Printf("%T\n", xx) }
retype---------- float32
文字列→数値変換
import ( "fmt" "strconv" ) func main(){ fmt.Println("strconv----------") var s string = "999" // i, _ := stconv.Atoi(s) i, err := strconv.Atoi(s) if err != nil { fmt.Println("Error") } fmt.Printf("%v %T\n", i, i) }
strconv---------- 999 int
配列の定義
ここでは長さ2の配列を定義した為、可変ではないことに注意。
func main(){ fmt.Println("list----------") var aa [2]int aa[0] = 1 aa[1] = 2 fmt.Println(aa) }
list---------- [1 2]
可変配列の定義
可変配列を定義したい場合は、長さを指定しません。
加えて、スライスは以下のように定義します。
func main(){ fmt.Println("list----------") var bb []int = []int{200, 300} bb = append(bb, 300, 400, 500) fmt.Println(bb) fmt.Println(bb[2]) fmt.Println(bb[2:5]) fmt.Println(bb[:]) }
list---------- [200 300 300 400 500] 300 [300 400 500] [200 300 300 400 500]
二重配列
func main(){ var board = [][]int{ []int{0,1,2}, []int{0,1,2}, []int{0,1,2}, } fmt.Println("list----------") fmt.Println(board) }
list---------- [[0 1 2] [0 1 2] [0 1 2]]
make
後に2つの組み込み関数(make vs new)の比較で頭がこんがらがります。
makeに割り当てられるのは、スライス、マップ、チャネルのみです。
makeでは初期化された、すなわちゼロ値でないT型(Type)を返します。
スライスはデータ(配列内)へのポインタ、長さ、キャパシティで成り立っていて、
初期化されるまでは要素の値はNilとなっています。
func main(){ fmt.Println("make capacity----------") naa := make([]int, 3, 5) naa = append(naa, 2, 3) naa = append(naa, 2, 3) fmt
make capacity---------- len=7 cap=10 value=[0 0 0 2 3 2 3]
makeで空配列作成
func main(){ fmt.Println("make capacity----------") aa := make([]int, 0) var bb []int fmt.Printf("len=%d cap=%d value=%x\n", len(aa), cap(aa), aa) fmt.Printf("len=%d cap=%d value=%x\n", len(bb), cap(bb), bb) }
make capacity---------- len=0 cap=0 value=[] len=0 cap=0 value=[]
連想配列
連想配列では存在しないキーの追加も行うことも可能だが、初期時点で連想配列が空の場合はエラー。
空配列はNilとして判定されるので注意が必要。
func main(){ fmt.Println("map--------------------") m := map[string]float32{"yoshida": 0.350, "yanagita": 0.342, "kondo": 0.341} fmt.Println(m) m["yoshida"] = 0.389 fmt.Println(m) value, _ := m["yamamoto"] fmt.Println(value) // var lis[]int -> 空(Nil) }
map-------------------- map[kondo:0.341 yanagita:0.342 yoshida:0.35] map[kondo:0.341 yanagita:0.342 yoshida:0.389] 0
関数の使い方
func add(x int, y int) (int, int) { return x + y, x-y } func main(){ fmt.Println("function--------------------") nadd, adelta := add(10, 20) fmt.Printf("add: %d , delta: %d", nadd, adelta) }
function-------------------- add: 30 , delta: -10
関数の使い方(返り値を指定)
返り値の変数と型を指定することも可能です。
func cal(block, number int)(all int){ all = block * number return } func main(){ all := cal(100, 2000) fmt.Printf("ブロックの総数が%d個です", all) }
ブロックの総数が200000個です
即時関数・無名関数
func main(){ function1 := func(x int){ fmt.Println("function1 : ", x) } function1(100) func(x int){ fmt.Println("function2 : ", x) }(100) }
function1 : 100 function2 : 100