17
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go言語 チートシート

Last updated at Posted at 2018-11-14

概要

Go言語をおさらいする必要があったので、公式 で勉強しながらチートシートを作りました。
間違いや情報が古い等ありましたらコメント頂けると幸いです。

内容

A Tour of Go の順番で作った。

  • パッケージ
  • 変数
  • 関数
  • 基本制御構文
  • 遅延処理
  • ポインタ
  • 構造体
  • 配列
  • スライス
  • マップ
  • メソッド
  • インタフェース
  • エラー
  • その他標準ライブラリ
  • 非同期処理

パッケージ

Go のプログラムは package で構成される。
プログラムは main パッケージから開始される。
fmt 等は標準のパッケージ、import で読み込む。

変数

// 通常の宣言
var x int

// 型名省略可能
var x, y = 1, "true"

// 暗黙的な型宣言
x := 1

// 定数
const X = 1

関数

一般的な言語の関数と変わらない。
ただし、Goの関数はクロージャの為、それ自信の外部から変数を参照する。

// 構文
func 関数名(変数名 型名, 変数名 型名) 返り値型名 { }

// 大文字で始まる関数はパッケージ外からアクセス可能
func Add(x int, y int) int { }

// 小文字で始まる関数はパッケージ外からアクセス不可
func add(x int, y int) int { }

// 引数の型が同じ場合はまとめる
func add(x, y int) int { }

// 関数値
f := func(x, y int) int { }
f(1, 2)

基本制御構文

// 繰り返し
for i := 0 ; i < 10 ; i++ { }

// while
for i < 10 { }

// 無限ループ
for { }

// 分岐
if x < 0 { }

// ifのショートステートメント
if v := add(x, y); v < 10 { }

// switch 
switch v := add(x, y); v {
case 1:
  // 処理 (breakは必要無い)
default:
  // 処理
}

// 条件の無いswitch
switch {
case v < 10:
  // 処理
}

遅延処理

defer を使用。
defer が付いている関数呼び出しは関数の return 時に行われる。
ただし、引数の評価はすぐに行われる。

defer add(x, y)

ポインタ

Goはポインタを扱い、ポインタは値のアドレスを指す。
ゼロ値のポインタは nil になる。

// ポインタ
var p *int

// &演算子 (ポインタを引き出す)
i := 42
p = &i

// *演算子 (ポインタの指す変数を示す)
fmt.Println(*p) // 42
*p = 21 // ポインタpを通して変数iに代入

構造体

構造体はフィールドの集合である。
先頭大文字、小文字のルールは関数と同じ。

// 構造体の定義
type Point struct {
  X int
  Y int
}

// 構造体の初期化
p := Point{1, 2}

// フィールドを指定して初期化
p := Point{X: 1, Y: 2}

// 省略して初期化 (ゼロ値が入る)
p := Point{X: 1}
p := Point{}

// ポインタを返して初期化
v := &Point{1, 2}

// フィールドへアクセス
p.X = 10

// ポインタを通してアクセス
v := &p
(*v).X = 15 
v.X = 5 // *演算子は省略可能

配列

配列の長さは型の一部分であるため、サイズを変えることは出来ない。

// 宣言
var a [3]int

// 初期化
a := [3]int{1,2,3}

// アクセス
a[0] = 1

スライス

配列は固定長だが、スライスは可変長。
Goでは配列よりもスライスの方が一般的。

スライスは配列への参照のようなもので、実際にデータを持っていない。
スライスは配列の部分列を指し示し、スライスの変更は配列にも影響する。

// 宣言
var s []int

// 既存の配列からスライスを作る
var s []int = a[1:4] // 1番目から3番目の要素で作る

// スライスの省略
var s[]int = a[:4] // 0番目から3番目
var s[]int = a[1:] // 1番目から最後尾まで
var s[]int = a[:] // 0番目から最後尾まで

// 新規の配列からスライスのみを取得する
s := []int{1, 2, 3}

// 長さ (スライスの要素数) の取得
len(s)

// 容量 (スライスの最初の要素から数えて、元配列の要素数) の取得
cap(s)

// 動的サイズの配列の作成
s := make([]int, 長さ, 容量)

// 多次元スライス
board := [][]string{
  []string{"_", "_", "_"},
  []string{"_", "_", "_"},
  []string{"_", "_", "_"},
}
board[0][0] = "X"

// 要素の追加 (長さは追加した数だけ増え、容量は足りない時に多めに自動確保する)
append(s, 追加したい値, 追加したい値...)

// リストの走査 (i はインデックス, v は値のコピー)
for i, v := range s { }
for _, v := range s { } // インデックスの破棄
for i := range s { } // 値の破棄

マップ

map はキーと値を関連付ける。

// 宣言
m := make(map[string]int)

// リテラル
var m = map[string]int{
  "one": 1,
  "two": 2,
}

// アクセス
m["one"] = 1

// 要素の削除
delete(m, key)

// キーの存在確認
elem, ok := m[key] // 存在すれば ok は true, しなければ false

メソッド

Go にはクラスが無いが、型にメソッドを定義出来る。
メソッドはレシーバ引数を関数に取る。

// Point型を定義
type Point struct {
  X, Y int
}

// Point型にメソッドを定義
func (p Point) Add() int {
  return p.X + p.Y
}

// メソッド呼び出し
p := Point{1, 2}
p.Add()

// ポインタレシーバ (レシーバ自身を更新出来る)
func (p *Point) Up() {
  p.X += 1
}

インタフェース

interface型はメソッドのシグネチャの集まりで定義される。
これを実装した値を、interface型の変数へ持たせることが出来る。
JavaとかのInterfaceと雰囲気同じ。

// 型定義
type Point struct {
  X, Y int
}

// インタフェース定義
type Calculator interface {
  Add(int, int) int
}

// インタフェース実装 (implementsキーワードは必要無い)
func (p Point) Add(x, y int) int {
  return p.X + p.Y
}

// 代入
var c Calculator
p := Point{1, 2}
c = &p

エラー

Go言語では、エラー状態を error 値で表現する。
error 型は組み込みインタフェースである。

// error型の定義
type error interface {
  Error()  string
}

// エラーチェック (nilなら成功, nilでなければ失敗)
i, err := f()
if err != nil {
  fmt.Printf("%v¥n", err)
  return
}

その他標準ライブラリ

  • データストリームの読み込み
  • インタフェース
  • ファイル
  • ネットワーク接続
  • 圧縮
  • 暗号化
  • etc...

詳細は公式を参照。

非同期処理

goroutine を利用する、これはGoのラインタイムに管理される軽量スレッドである。
go f(x) と書くと新しい goroutine が実行される。
引数の評価は呼び出し元の goroutine で行われ、関数の実行は新しい goroutine が作られる。

goroutine は同じアドレス空間を利用するので、共有メモリアクセスは必ず同期する。
同期には channel を利用すると良い。
詳しくは公式参照。

まとめ

17
19
1

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
17
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?