Golang
Packages, Valiables and Functions
Packages
- Go のプログラムはパッケージで成り立っている
main
パッケージのmain
関数からプログラムが始まる- パッケージ名はインポートパスの最後の 要素と同じ名前である(
math/rand
ならrand
) - 一つのフォルダには一つのパッケージしか含められない(例外は
フォルダ名_test
)。通常はフォルダ名をパッケージ名にする。
Imports
// bad
import "fmt"
import anotherName "math"
import _ "io" // 初期化処理だけ使いたい場合
// good (factored import)
import (
"fmt"
anotherName "math"
import _ "io"
)
Exported names
- 大文字で始まる名前がエクスポートされる
- パッケージをインポートしたとき、エクスポートされた名前のみ参照できる
Functions
- 各引数の後に型を記載する
()
の後に返値の型を記載する
func add(x int, y int) int {
return x + y
}
// 連続する引数が同じタイプなら省略できる
func add(x, y int) int {
return x + y
}
Multiple results
ファンクションは複数の値を返すことができる。
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b) // => world hello
}
Named return values
- 戻り値に名前をつけると、関数の最初で定義した変数として扱われる
- 名前付き戻り値を使い、かつ return に何も書かなかった場合、自動的に名前付き戻り値がリターンされる(naked return)。ただし、長い関数では読みやすさ の点から明示的に記載すること。
- 戻り値の意味を表す名前をつけるよう心がけること
func split(sum int) (x, y int) {
x = sum / 2
y = sum - x
return
}
func main() {
a, b := split(20)
fmt.Println(a, b)
}
値渡しと参照渡し
- 関数に引数を渡した場合、値はコピーされる。つまり、呼び出し元の変数とは別物である。
- 下記の場合、
i
はmyInt
のコピーであり、p
はmyPointer
のコピーである。
func test(i int, p *int) {}
func main() {
myInt := 123
myPointer := &myInt
test(myInt, myPointer)
}
可変長パラメータ
- 最後の引数に限って、
...
をつけることで可変長のパラメータとして受け取れる - 受け取ったパラメータはスライスとして扱われる。
// c の型は []string になる
func someFunc(a int, b int, c ...string){}
関数リテラル
- 匿名関数(クロージャ)を作るときに使う
- 記法としては、通常の関数宣言から名前を削除するだけ
- リテラルの外側の変数にアクセス可能
- 名前がないので、関数を呼び出す際には、IIFE にするか、変数に代入して後から呼び出す。
// 関数リテラル
func (a int, b int) int {}
関数型
- 関数 を変数に代入するときの型として扱うためのもの
- 引数名は省略可能であり、通常は書かない
// 関数型の宣言
var a func(int, int) int
// 実装
a = func(a int, b int) int {}
Variables
var
で変数を宣言できる。
// 複数の同じ型の変数はまとめて宣言できる。
var a, b, c bool
func main() {
var d int
fmt.Println(a, b, c, d) // => false false false 0
}
Initializers
宣言時に内容を設定する場合は、型定義を省略できる。
var a, b, c = 1, true, "no!"
// or factored style
var (
a = 1
b = true
c = no
)
fmt.Println(a, b, c) // => 1 true "no!"
Short variable declarations
- ファンクションの中であれば、
:=
を使うことでvar
を省略できる。 - ファンクションの外では、すべての Statement は
var
,func
,import
などのキーワードから始まる必要があるため、省略形は使えない。
func someFunc() {
a, b, c := 1, true, "no!"
fmt.Println(a, b, c) // => 1 true "no!"
}
Basic types
int
,uint
,uintptr
は、32bit システムでは 32bit、64bit システムでは 64bit である。- 特に理由がなければ、サイズ指定やアンサインドは使わず、
int
を使うこと。
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr (u = unsigned)
byte // alias for uint8
rune // alias for int32
// represents a Unicode code point
float32 float64
complex64 complex128
Zero values
明示的に初期値を設定しない限り、変数には「Zero Values」がセットされる
type | value |
---|---|
数値 | 0 |
boolean | false |
文字列 | "" (空文字列) |
struct | 各フィールドがゼロ値の struct |
配列、スライス | 各要素がゼロ値の配列 |
マップ | 空のマップ? |
その他(ポインタ、関数型など) | nil |
var a int // => 0
var b float64 // => 0
var c bool // => false
var d string // => ""
Type conversions
Type(value)
の形で型変換を行える。
var i float64 = float64(123)
j := uint(456)
Type inference
- 明示的に型を指定しなかった場合は、右辺の値から型推論される。
- 数値の場合は、必要な精度により、適切な方が自動で選択される。
var i = 1 // int
j := 1 // int
a := 42 // int
b := 3.142 // float64
c := 0.867 + 0.5i // complex128
Constants
- 定数には文字列、ブーリアン、数値を使うことができる。
:=
記法は使えない
const Pi float64 = 3.14
const (
A int = 123
B string = "hello"
)