- A Tour of Go
- Variables
- Variables with initializers
- Short variable declarations
- Basic types
- Zero values
- Type conversions
- Type inference
- Constants
- Numeric Constants
- Go, Go, Go, Go 〜 (郷ひろみ風)
A Tour of Go
https://go-tour-jp.appspot.com/ を写経していく.
Variables
- https://go-tour-jp.appspot.com/basics/8
- var ステートメントは変数 (variable) を宣言する
- 関数の引数リストと同様に, 複数の変数の最後に型を書くことで変数のリストを宣言することが出来る
- var ステートメントはパッケージ、または、関数で利用出来る
// filename: variables.go package main import "fmt" var c, python, java bool func main() { var i int fmt.Println(i, c, python, java) }
以下, 実行結果.
$ ./_run.sh variables.go 0 false false false
Variables with initializers
- https://go-tour-jp.appspot.com/basics/9
- var 宣言では, 変数毎に初期化子 (initializer) を与えることができる
- 初期化子が与えられている場合は型を省略出来, その変数は初期化子が持つ型となる
// filename: variables-with-initializers.go package main import "fmt" var i, j int = 1, 2 func main() { var c, python, java = true, false, "no!" fmt.Println(i, j, c, python, java) }
以下, 実行結果.
$ ./_run.sh variables-with-initializers.go 1 2 true false no!
あまり関係ないかもしれないけど, 変数にスコープって存在しないのかなと思ったりした.
Short variable declarations
- https://go-tour-jp.appspot.com/basics/10
- 関数の中では, var 宣言の代わりに, 短い
:=
の代入文を使って暗黙的な型宣言が出来る - 関数外では, キーワードではじまる宣言 (var, func, など) が必要で
:=
での暗黙的な宣言は利用出来ない
// filename: short-variable-declarations.go package main import "fmt" func main() { var i, j int = 1, 2 k := 3 c, python, java := true, false, "no!" fmt.Println(i, j, k, c, python, java) }
変数 k
は var
で宣言されていないが, 代入文として :=
が利用されている為, 3
が代入されている.
$ ./_run.sh short-variable-declarations.go 1 2 3 true false no!
Basic types
Go 言語の基本型 (組み込み型) は以下の通り.
bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // uint8 の別名 rune // int32 の別名 // Unicode のコードポイントを表す float32 float64 complex64 complex128
- https://go-tour-jp.appspot.com/basics/11
- int, uint, uintptr 型は, 32-bit のシステムでは 32 bit で, 64-bit のシステムでは 64 bit を表現する
- サイズ, 符号なし (unsigned) 整数の型を使うための特別な理由がない限り, 整数の変数が必要な場合は int を使うようにする
// filename: basic-types.go package main import ( "fmt" "math/cmplx" ) var ( ToBe bool = false MaxInt uint64 = 1<<64 - 1 z complex128 = cmplx.Sqrt(-5 + 12i) ) func main() { fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe) fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt) fmt.Printf("Type: %T Value: %v\n", z, z)
以下, 実行結果.
$ ./_run.sh basic-types.go Type: bool Value: false Type: uint64 Value: 18446744073709551615 Type: complex128 Value: (2+3i)
%T
で変数の型, %v
で変数の中身にアクセスすることが出来るようだ.
// filename: basic-types2.go package main import ( "fmt" ) var ( Foo string = "Foo" ) func main() { fmt.Printf("Type: %T Value: %v\n", Foo, Foo) }
以下, 実行結果.
$ ./_run.sh basic-types2.go Type: string Value: Foo
Zero values
- https://go-tour-jp.appspot.com/basics/12
- 変数に初期値を与えずに宣言すると, ゼロ値 (zero value) が与えられる
- ゼロ値は型によって以下のように与えられる
- 数値型 (int,float など): 0
- bool 型: false
- string 型: "" (空文字列 (empty string))
// filename: zero.go package main import "fmt" func main() { var i int var f float64 var b bool var s string fmt.Printf("%v %v %v %q\n", i, f, b, s) }
以下, 実行結果.
$ ./_run.sh zero.go 0 0 false ""
Type conversions
- https://go-tour-jp.appspot.com/basics/13
- 型の変換
- 変数
v
, 型T
があった場合,T(v)
は, 変数v
をT
型へ変換する
以下, 変換の例.
var i int = 42 var f float64 = float64(i) var u uint = uint(f) # よりシンプルに i := 42 f := float64(i) u := uint(f)
C 言語とは異なり, Go での型変換は明示的な変換が必要となる.
// filename: type-conversions.go package main import ( "fmt" "math" ) func main() { var x, y int = 3, 4 var f float64 = math.Sqrt(float64(x*x + y*y)) var z uint = uint(f) fmt.Println(x, y, z) }
以下, 実行結果.
$ ./_run.sh type-conversions.go 3 4 5
以下, float64
に型変換しなかった場合の実行結果.
$ ./_run.sh type-conversions.go # command-line-arguments /sandbox/type-conversions.go:11:33: cannot use x * x + y * y (type int) as type float64 in argument to math.Sqrt
Type inference
- https://go-tour-jp.appspot.com/basics/14
- 明示的な型を指定せずに変数を宣言する場合 (:= や var = のいずれか), 変数の型は右側の変数から型推論される
- 以下のように, 右側の変数が型を持っている場合, 左側の新しい変数は同じ型になる
var i int j := i // j の型は int になる
上記を念の為, 確認する.
// filename: type-inference-check1.go package main import ( "fmt" ) func main() { var i int = 100 j := i fmt.Printf("Type: %T Value: %v\n", j, j) }
実行してみると...
$ ./_run.sh type-inference-check.go Type: int Value: 100
右側に型を指定しない数値である場合, 左側の新しい変数は右側の定数の精度に基いて int, float64, complex128 の型となる.
i := 42 // int f := 3.142 // float64 g := 0.867 + 0.5i // complex128
こちらも念の為に確認.
// filename: type-inference-check2.go package main import ( "fmt" ) func main() { i := 42 f := 3.142 g := 0.867 + 0.5i fmt.Printf("Type: %T Value: %v\n", i, i) fmt.Printf("Type: %T Value: %v\n", f, f) fmt.Printf("Type: %T Value: %v\n", g, g) }
実行してみると...
$ ./_run.sh type-inference-check2.go Type: int Value: 42 Type: float64 Value: 3.142 Type: complex128 Value: (0.867+0.5i)
以下, ツアーのコード.
// filename: type-inference.go package main import "fmt" func main() { v := 42 // change me! fmt.Printf("v is of type %T\n", v) }
以下, 実行.
$ ./_run.sh type-inference.go v is of type int
例えば, v の値を "foo"
にした場合には以下のような結果となった.
$ ./_run.sh type-inference.go v is of type string
Constants
- https://go-tour-jp.appspot.com/basics/15
- 定数 (constant) は, const キーワードを使って変数と同じように宣言可
- 定数は, 文字 (character), 文字列 (string), boolean, 数値 (numeric) のみで利用可能
- 定数は := を使って宣言不可
// filename: constants.go package main import "fmt" const Pi = 3.14 func main() { const World = "世界" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) }
以下, 実行結果.
$ ./_run.sh constants.go
Hello 世界
Happy 3.14 Day
Go rules? true
Numeric Constants
- https://go-tour-jp.appspot.com/basics/16
- 数値の定数は, 高精度な値 (values) である
- 型のない定数は, その状況によって必要な型を取る
// filename: numeric-constants.go package main import "fmt" const ( // Create a huge number by shifting a 1 bit left 100 places. // In other words, the binary number that is 1 followed by 100 zeroes. Big = 1 << 100 // Shift it right again 99 places, so we end up with 1<<1, or 2. Small = Big >> 99 ) func needInt(x int) int { return x*10 + 1 } func needFloat(x float64) float64 { return x * 0.1 } func main() { fmt.Println(needInt(Small)) fmt.Println(needFloat(Small)) fmt.Println(needFloat(Big)) }
以下, 実行例.
$ ./_run.sh numeric-constants.go 21 0.2 1.2676506002282295e+29
コードの needInt(Big)
を出力した場合...
$ ./_run.sh numeric-constants.go # command-line-arguments /sandbox/numeric-constants.go:20:21: constant 1267650600228229401496703205376 overflows int
int は 64-bit の整数を保持出来るが, それでは足りないことがある場合に const を活用する.
Go, Go, Go, Go 〜 (郷ひろみ風)
以上, Basics が終了〜でした.