何かやってみるブログ

興味をもったことに関して書いています。技術系の記事が多いです。

Goの文法まとめ(型・配列・スライス・配列・Map・クロジャーなど)

最近、個人的な趣味でGoを勉強しているのでメモ代わりに残します.

Hello World

package main

import "fmt"

//最初に呼ばれる
func init(){
   fmt.Println("Initialize")
}

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

// => Initialize
//    Hello World

https://go-tour-jp.appspot.com/welcome/1

Import

package main

import(
  "fmt"
  "time"
)

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

// =>  Hello World 2020-07-01 03:26:01.271134 +0900 JST m=+0.000122134

packageは以下から参照できる

https://golang.org/pkg/ 

変数宣言

package main

import "fmt"

//関数外でも宣言できる
var num int = 10
var str string = "Hello World"
var t, f bool = true, false
var x64 float64 = 1.23

func main() {
    //関数内のみ宣言できる
    x := 12
    y := 14

    fmt.Println(x + y)
    fmt.Println(num, str, t, f, x64)
    fmt.Printf("%T \n", x64)
}

// => 26
// => 10 Hello World true false 1.23
// => float64 

https://go-tour-jp.appspot.com/basics/10

const

package main

import "fmt"

//定数
const Pi = 3.14

func main() {
    fmt.Println(Pi)
}

// => 3.14

https://go-tour-jp.appspot.com/basics/15

数値型

package main

import "fmt"

func main() {
    x := 0
    fmt.Println(x)
    x++
    fmt.Println(x)
    x--
    fmt.Println(x)

    //シフト演算
    fmt.Println(1 << 0)
    fmt.Println(1 << 1)
    fmt.Println(1 << 2)
    fmt.Println(1 << 3)
}

// 0
// 1
// 0
// 1
// 2
// 4
// 8

https://go-tour-jp.appspot.com/basics/16

文字列型

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println("Hello World")
    fmt.Println("Hello" + "World")
    fmt.Println("Hello World"[0])         //72
    fmt.Println(string("Hello World"[0])) // H
    var s string = "Hello World"
    fmt.Println(strings.Replace(s, "H", "X", 1)) // Xello World
    fmt.Println(`test
                test
                    `)
}

// Hello World
// HelloWorld
// 72
// H
// Xello World
// test
//                                   test

論理値型

package main

import (
    "fmt"
)

func main() {
    t, f := true, false
    fmt.Printf("%T %v \n", t, t) // bool true
    fmt.Printf("%T %v \n", f, f) // bool false

    fmt.Println(true && true)   //true
    fmt.Println(true && false)  //false
    fmt.Println(false && false) //false

    fmt.Println(true || true)   //true
    fmt.Println(true || false)  //true
    fmt.Println(false || false) //false

    fmt.Println(!true)  //false
    fmt.Println(!false) // true
}

型変換

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var x int = 1
    xx := float64(x)
    fmt.Printf("%T %v  %f\n", xx, xx, xx)

    var y float64 = 1.2
    yy := int(y)
    fmt.Printf("%T %v %d \n", yy, yy, yy)

    var z string = "14"
    zz, _ := strconv.Atoi(z)
    fmt.Printf("%T %v %d \n", zz, zz, zz) //14
}

// float64 1  1.000000
// int 1 1 
// int 14 14 

配列

package main

import "fmt"

func main() {

        // 以下は配列
    var arr [2]int
    arr[0] = 100
    arr[1] = 200
    fmt.Println(arr)

    var arr2 [2]int = [2]int{100, 200}
    fmt.Println(arr2)

        // 以下はスライス
    var b []int = []int{100, 200}
    b = append(b, 300)
    fmt.Println(b)
}

// [100 200]
// [100 200]
// [100 200 300]

配列は固定長です. 一方で、スライスは可変長です.

https://go-tour-jp.appspot.com/moretypes/6

スライス

package main

import "fmt"

func main() {
    n := []int{1, 2, 3, 4, 5, 6}
    fmt.Println(n)
    fmt.Println(n[1])
    fmt.Println(n[2:4])
}

// [1 2 3 4 5 6]
// 2
// [3 4]

https://go-tour-jp.appspot.com/moretypes/8

make

package main

import "fmt"

func main() {
    c := make([]int, 0, 5)
    fmt.Println(cap(c))
    for i := 0; i < 5; i++ {
        c = append(c, i)
        fmt.Println(c)
    }
    fmt.Println(c)
    fmt.Println(cap(c))
}

// 5
// [0]
// [0 1]
// [0 1 2]
// [0 1 2 3]
// [0 1 2 3 4]
// [0 1 2 3 4]
// 5

make関数を使ってスライスを作ることもできる. https://go-tour-jp.appspot.com/moretypes/13

Map

package main

import "fmt"

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

    v, ok := m["apple"]
    fmt.Println(v, ok)
}

// 100
// map[apple:100 banana:200]
// 0
// 100 true

RubyでいうところのHash、JavaScriptで言えばオブジェクトみたいな感じ.

https://go-tour-jp.appspot.com/moretypes/19

Byte

package main

import "fmt"

func main() {
    c := []byte{72, 73}
    fmt.Println(c)
    fmt.Println(string(c))

    d := []byte("HI")
    fmt.Println(d)
    fmt.Println(string(d))
}

関数

package main

import "fmt"

func add(x int, y int) (int, int) {
    //fmt.Println("add function")
    //fmt.Println(x + y)
    return x + y, x - y
}

func cal(item, price int) (result int) {
    result = price * item
    return
}

func main() {
    fmt.Println(add(2, 3))
    fmt.Println(cal(100, 300))

    f := func() {
        fmt.Println("Inner function")
    }

    f()
}

// 5 -1
// 30000
// Inner function

https://go-tour-jp.appspot.com/basics/4

クロージャー

package main

import "fmt"

func countGenerator() func() int {
    x := 0
    return func() int {
        x++
        return x
    }
}


func main() {
    counter := countGenerator()
    fmt.Println(counter())
    fmt.Println(counter())
    fmt.Println(counter())
}

// 1
// 2
// 3

外部から関数内の変数にアクセスできる.

関数を返すFunction クロージャーもある. https://go-tour-jp.appspot.com/moretypes/25