はじめに
Goプログラムで使われる基本文法を学習したのでまとめておきます。
できるだけ簡潔明瞭に書いたつもりです。これからGoを始める方の参考になれば幸いです。
今回は「基礎」として、Goプログラミングの概念や仕組みを含む以下に関する内容となります。
目次
- Packages : パッケージ
- Exported Names : 外部パッケージからのエクスポート
- Functions : 関数
- Variables : 変数
- Zero Values : ゼロ値
- Basic Types : 基本型
- Type Conversions : 型変換
- Constants : 定数
- Scope : スコープ
- 参考文献
Packages : パッケージ
Goプログラムは、パッケージで構成されています。
・プログラムのエントリポイント(一番最初に実行)は main
パッケージ
・パッケージ名はインポートパスの最後の要素と同名
"math/rand" ⇨ package rand
ファイル群の import を行なっている
・パッケージのインポート方法は2種類
① "fmt" と "math/rand" パッケージを一括インポート(factored import statement)
② "fmt" と "math/rand" パッケージを個別インポート
package main
// ①
import (
"fmt"
"math/rand"
)
func main() {
// rand.Intn()で乱数を出力
fmt.Println("My favorite number is", rand.Intn(10)) // => My favorite number is ランダム値
}
// ②
import "fmt"
import "math/rand"
fmt
:データの入出力機能がまとめられたパッケージ
https://pkg.go.dev/fmt#pkg-functions
math
:計算機能がまとめられたパッケージ
https://pkg.go.dev/math
Exported Names : 外部パッケージからのエクスポート
Goでは、最初の文字が大文字で始まる名前はExported Names
と呼ばれ、外部パッケージからエクスポートされたものです。
・Pi
は math パッケージからエクスポートされたもので円周率を示す定数名
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.Pi) // => 3.141592653589793
}
ちなみに、math.pi
とパッケージ内でエクスポートされていない(存在しない)名前へアクセスした場合はundefined: math.pi
エラーとなります。
Functions : 関数
関数は0個以上の引数を取ることができます。
関数の定義は以下です。
func <関数名>(引数) 戻り値の型 {
関数の本体
}
引数が複数でそれらが同種類の場合はx, y int
の通り、型の省略が可能です。
package main
import "fmt"
// 引数1つ
func str(i string) string{
return i
}
// 引数2つ
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(str("Hello World")) // => Hello World
fmt.Println(add(42, 13)) // => 29
}
複数の戻り値を返すことも可能です。
package main
import "fmt"
// 文字列を入れ替える関数
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b) // => world hello
}
Variables : 変数
変数の定義は2種類で、明示的な定義と暗黙的な定義があります。
・明示的な定義 : var 変数名 変数の型
・暗黙的な定義 : 変数名 := 変数の値
もしくはvar 変数名 = 変数の値
⇨ 型推論が行われ、型指定の必要がない
⇨ 関数の外では宣言できない
変数の種類は2種類でローカル変数とパッケージ変数があります。
・ローカル変数 : 任意の関数の中に定義された変数
・パッケージ変数 : 関数定義の外部に定義された変数
package main
import (
"fmt"
)
var p = 100 // パッケージ変数
func main() {
// 明示的な定義
// 型別に個別宣言
var a, b, c, d int
var e string
a, b, c, d = 1, 3, 5, 7
e = "golang!"
fmt.Println(a, b, c, d) // => 1, 3, 5, 7
fmt.Println(e) // => golang!
// 複数の型を一括宣言
var (
f, g, h, i int
j string
)
f, g, h, i = 2, 4, 6, 8
j = "hello world"
fmt.Println(f, g, h, i) // => 2, 4, 6, 8
fmt.Println(j) // => hello world
// 暗黙的な定義
// 個別宣言
w1 := 1
x1 := true
y1 := 12.3
z1 := "abc"
fmt.Println(w1, x1, y1, z1) // => 1, true, 12.3, abc
// 一括宣言
var (
w2 = 2
x2 = false
y2 = 56.7
z2 = "def"
)
fmt.Println(w2, x2, y2, z2) // => 2, false, 56.7, def
// ローカル変数、パッケージ変数参照
var l = 50 // ローカル変数
pl = p + l // パッケージ変数は参照可能
fmt.Printf("p=%d\n", p) // => p=150
}
Zero Values : ゼロ値
変数へ初期値を与えずに宣言すると、ゼロ値が与えられます。
ゼロ値は型によって以下の通りとなります。
・数値型(int,floatなど) : 0
・bool型 : false
・string型 : "" (空文字列)
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) // => 0 0 false ""
}
Basic Types : 基本型
Goで扱われる型の種類です。
・int
, uint
, uintptr
型は、32-bitシステムでは32 bit、64-bitシステムでは64 bit
・整数の変数が必要な場合、基本的にはint
を使うべし!!!
・変数宣言は、インポートステートメントと同様に、まとめて( factored )宣言可能
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 の別名
rune // int32 の別名
// Unicode のコードポイントを表す
float32 float64
complex64 complex128
Type Conversions : 型変換
静的言語であるGoでは暗黙的な型変換は行われないので、異なる型の変数への代入はエラーとなります。
var i int = 10
var f float32 = i // => cannot use i (type int) as type float32
型変換の定義は以下です。
var 変数名 変数後の型 = 変数後の型(変換する値)
var i uint32 = 1234567890
var f uint8 = uint8(i) // uint32 ⇨ uint8 への型変換
fmt.Println(f) // => 210(情報が欠落する)
Constants : 定数
定数は const キーワードを使って変数と同様に宣言します。
・型なし定数(untyped)と型あり定数(typed)の2種類が存在
・文字(character)、文字列(string)、boolean、数値(numeric)のみで使用可能
・:=
で宣言することはできない
package main
import "fmt"
// 型なし定数
const Pi = 3.14
func main() {
const Constants = "定数"
fmt.Println("Hello", Constants) // => Hello 定数
fmt.Println("Happy", Pi, "Day") // => Happy 3.14 Day
const Truth = true
fmt.Println("Go rules?", Truth) // => Go rules? true
// 型あり定数
const (
X int64 = -1
Y float64 = 1.2
)
fmt.Println(X, Y) // => -1, 1.2
}
Scope : スコープ
パッケージに定義された定数、変数、関数などの識別子の1文字目を大文字にすることで他のパッケージからそれらの値を参照できる。
・スコープ対象は[スコープ対象のパッケージ名] [インポートパス]
の定義でインポート
・スコープ対象の識別子1文字目が小文字の場合はエラー扱い
package scope_target
const (
MAX = 100
internal_val = 1
)
func Scope(i int) int {
return internalAdd(i)
}
func internalAdd(i int) int {
return i + 1
}
package main
import (
"fmt"
scope_target "go_next_app/test" // scope_target パッケージをインポート
)
func main() {
// scope_target パッケージで定義された定数、変数、関数を参照(スコープ)
w := scope_target.MAX
x := scope_target.internal_val
y := scope_target.Scope(5)
z := scope_target.internalAdd(5)
fmt.Println(w) // => 100
fmt.Println(x) // => error:「undefined: scope_target.internal_const」
fmt.Println(y) // => 6
fmt.Println(z) // => error:「internalFunc not exported by package scope_target」
}