post Image
ざっくりGoの文法まとめ

概要

復習も兼ねて、Go言語の文法を簡単にまとめた。

環境設定は以下を参照。
http://qiita.com/chrischris0801/items/ce1d3a493750f67167ec

基本

main.go
// コメントは「//」で書く
// Go言語のソースファイルは必ずpackageで始まる
package main

// fmtパッケージをインポートする
import "fmt"

// main関数
func main() {
    fmt.Println("main")
}

package

Go言語のソースファイルはなんらかのpackageに属さなければいけない。
多数のソースファイルのうちの少なくとも1つはmainパッケージに属させないといけない。

import

外部のソースやパッケージを利用する際には import で追加する。

func

関数の宣言は func によって行う。

ソースコードの実行

コマンドラインで $ go run filename と打つと、ソースファイルのコンパイルと実行を同時に行ってくれる。

$ go run main.go
main

変数

変数を宣言するときは型宣言もする。

// 方法1; 宣言する段階で値が決まっていない場合
var msg_1 string
msg_1 = "Hello, world"

// 方法2
var msg_2 = "Hello, world" // 初期化に使った型になる

// 方法3; 宣言する段階で値が決まっている場合
msg_3 := "Hello, world" // 宣言と代入を一気に行う

ゼロ値

変数宣言した時に値を指定しなかった場合、その変数には「ゼロ値」が設定される。

  • int: 0
  • float64: 0.0
  • string: “”
  • bool: false
  • Array: 各要素がゼロ値の配列
  • 構造体: 各フィールドがゼロ値の構造体
  • その他の型: nil

型変換

型の変換は以下のように行える。

// 変数の宣言
var i int = 1234

// intからstringへの変換
var s string = string(i)

演算子

演算子は他の言語と同じように、

  • 算術演算子: + – * /
  • 代入演算子: += -=
  • 比較演算子: == != < <= > >=
  • 論理演算子: && || !
  • インクリメント/デクリメント: ++ —

が使える。

Array

GoにはArrayとSliceがあり、Arrayは要素数が固定されているがSliceは要素数が固定されていない。

// [要素数]type{中身}
a := [3]int{1, 3, 5}

// 要素数は以下のように省略できる
b := [...]int{1, 3, 5}

型はいずれの場合も [3]int となる。
Arrayは長さ(length)と要素(element)の型を明らかにしたものであり、例えば[2]int[3]intでは違う型である。

Slice

SliceはArrayの要素数の規定が無いもので、長さ(len)と最大収容数(cap)を持つ。

// 方法1
s1 := []int{1, 3, 5}
len(s1) // 3

// 方法2; makeを使う
// capを省略すると、len == capとなる
s2 := make([]int, 3) // ゼロ値は[0,0,0]

// スライスの末尾に要素を追加
s1 = append(s1, 8, 2, 10)

マップ

keyもvalueも型を指定する。

// 変数の宣言
m := map[string]int{"kurisu":100, "ken":200}

// keyが"kurisu"の要素を削除
delete(m, "kurisu")

// 値を取り出す
// errの値も取り出す
value, err := m["ken"]

fmt.Println(value) // 200
fmt.Println(err) // nil

制御構文

if

point := 60;

if score > 80 {
    fmt.Println("Excellent")
} else if score > 60 {
    fmt.Println("Good")
} else {
    fmt.Println("Bad")
}

switch/case

default 句でいずれの場合(case)にも該当しなかった場合の処理を書きます。

switch.go
signal := "blue"

switch signal {
case "red":
    fmt.Println("Stop")
case "yellow":
    fmt.Println("Caution")
case "green", "blue":
    fmt.Println("Go")
// どのcase節にも一致しなかったときに実行される処理
default:
    fmt.Println("wrong signal")
}
$ go run switch.go
Go

for

単純な繰り返し処理では、for文を使います。
ループの終了には break を使い、スキップには continue を使う。

for i := 0; i < 10; i++ {
    // break: ループ終了
    if i == 3 { break }

    // fmtパッケージのPrintln関数
    fmt.Println(i)
}

range

Sliceやマップのループ処理には range を使う。

slice.go
s := []int{2, 3, 8}

// インデックスと要素を取り出す
for i, v := range s {
    fmt.Println(i, v)
}

// 要素のみを取り出したい場合
for _, v := range s {
    fmt.Println(v)
}

マップは以下のようにkeyとvalueを取り出す。

map.go
m := map[string]int{"taguchi":200, "fkoji":300}

// key, value
for k, v := range m {
    fmt.Println(k, v)
}

構造体とメソッドの定義

以下は四角形の構造体を定義し、面積を算出するメソッドを定義しているコード。

struct.go
package main

import "fmt"

// 構造体の定義
// type name struct { ...フィールド... }
type rect struct {
    width int
    height int
}

// メソッド; レシーバ付きの関数
// func (レシーバの変数名 レシーバの型) メソッド名(パラメータリスト) 戻り値の型 {
//   # 処理
//   return 戻り値
// }
func (r *rect) area() int {
    return r.width * r.height
}

// mainで実行する
func main() {
    // 構造体の初期化
    r := rect{width: 10, height: 5}
    fmt.Println("area: ", r.area())
}
$ go run struct.go
50

ポインタ

ポインタとは「あるメモリ領域を指し示すデータ」である。
変数を宣言すると、特定のメモリ領域に保存され、ポインタはその値を示すことになる。
ポインタを使うときは * と記述する。

レシーバの値を更新するようなメソッドでは、レシーバはポインタにしなければいけない。
レシーバにポインタを使うと、変数(構造体)のフィールドの値を変更することができるが、使わないと変更はもとの変数に反映されない。

// int型から新たにmyType型の構造体を宣言
type myType int

// レシーバが値(非ポインタ)のメソッド
func (value myType) setByValue(newValue myType) {
    value = newValue
}

// レシーバがポインタのメソッド
func (value *myType) setByPointer(newValue myType) {
    *value = newValue
}

func main() {
    var x myType = 0

    x.setByValue(1)
    fmt.Println(x) // xは0のまま

    x.setByPointer(1)
    fmt.Println(x) // xが1になる
}

コンポジション

構造体の中に構造体を埋め込むことができる。

package main

import "fmt"

type Person struct {
   Name string
   Address Address
}

type Address struct {
   Number string
   Street string
   City   string
   State  string
   Zip    string
}

func (p *Person) Talk() {
    fmt.Println("Hi, my name is", p.Name)
}

func (p *Person) Location() {
    fmt.Println("I’m at", p.Address.Number, p.Address.Street, p.Address.City, p.Address.State, p.Address.Zip)
}

func main() {
p := Person{
        Name: "Steve",
        Address: Address{
            Number: "13",
            Street: "Main",
            City:   "Gotham",
            State:  "NY",
            Zip:    "01313",
        },
    }

    p.Talk()
    p.Location()
}

インターフェース

PersonもCitizenも、Humanの一部であるので、Humanインターフェースを持つようにする。

type Human interface {
    Talk()
}

func SpeakTo(h Human) {
    h.Talk()
}

func main() {
    p := Person{Name: "Dave"}
    c := Citizen{Person: Person{Name: "Steve"}, Country: "America"}

    SpeakTo(&p)
    SpeakTo(&c)
}

Goroutineとchannel

goroutineは並行処理ができる機能で、channelは並行処理中に結果の受け渡しを行うための機能。

goroutine.go
package main

import (
    "fmt"
    "time"
)

func task1(result chan string) {
    time.Sleep(time.Second * 2)
    // channelに結果を出力する
    result<- "task1 result"
}

func task2() {
    fmt.Println("task2 finished")
}

func main() {
    // channel型のインスタンス
    result := make(chan string)

    // goroutineとして実行できる
    go task1(result)
    go task2()

    // task1の結果を取得する
    // 結果を取得できるまで待機している
    fmt.Println(<-result)

    time.Sleep(time.Second * 3)
}
$ go run goroutine.go
task2 finished
task1 result

『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。