【Go】Go言語特有の書き方

今回はGo言語特有の書き方の紹介です。
Goと他の言語で書き方が違うことがあるので、他の言語もこれからGoを学ぶ方も覚えておきましょう。
目次
変数宣言
Goでは、短縮記法の「 := 」がよく使われます。
name := "Kami"
age := 20
:= と _ の使い方
import {
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-lambda-go/lambdacontext"
}
func handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
lc, ok := lambdacontext.FromContext(ctx);
// 以下省略
}
- lc は *LambdaContext を受け取る変数。
- _ は 「使わないけど捨てられない戻り値」 のためのプレースホルダ。
ここでは bool(成功判定)を無視しています。
lc, ok := lambdacontext.FromContext(ctx);
_(ブランク識別子)とは?
- 「_」は使わない値を使用する
Goでは戻り値をすべて受け取らないとコンパイルエラーになるため、「使わない値」には _ を使います。
ブランク識別子を使った例
この関数はint 型(42)と、error 型(エラー)を返します。
func hogeFunc() (int, error) {
return 42, errors.New("エラー")
}
- 最初の int(この場合は 42) → 使わないから _ に捨てる
- 2つ目の error → err に格納する
_, err := hogeFunc() // 結果は無視、エラーだけ使う

簡単に_(ブランク識別子)を使った例で紹介すると分かりやすいですよね
スポンサードサーチ
エラーハンドリング
Goでは例外(try-catch)ではなく、「エラーは値として返す」のが一般
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer 文(処理の後回し)
Goでは、関数の終了時に何かを遅延実行したいときに defer を使います。
func readFile() {
f, _ := os.Open("file.txt")
defer f.Close() // ← 関数が終わる直前に実行される
// ファイルを読む処理...
}
スポンサードサーチ
並行処理(concurrency)
- go をつけるだけで別スレッド的に動く「ゴルーチン」が走ります。
- 超軽量スレッド。超低コスト。Goの代表的な機能!
go fetchData() // ← fetchData() を別ゴルーチンで並行実行
select 文(複数チャネルを同時に待つ)
他の言語であるswitch文と同じ使い方ですが、goではselect文になります。
select {
case msg := <-ch1:
fmt.Println("ch1から受信:", msg)
case msg := <-ch2:
fmt.Println("ch2から受信:", msg)
default:
fmt.Println("どこからもデータなし")
}
スポンサードサーチ
型スイッチ(type switch)
「どの型かによって処理を分ける」ことが簡単にできます。

interface{} + 型スイッチ、Goっぽい書き方ですね
func printType(x interface{}) {
switch v := x.(type) {
case string:
fmt.Println("文字列:", v)
case int:
fmt.Println("整数:", v)
default:
fmt.Println("未知の型")
}
}
初期化(init)
- main() より前に 自動的に呼ばれる特別な関数
- 複数定義してもOK(複数ファイルでも)
func init() {
fmt.Println("初期化中…")
}
無名関数(即実行関数)
JavaScriptのIIFEみたいな「書いた瞬間に実行する関数」。Goでも使われます!
func() {
fmt.Println("即時実行!")
}()
それぞれの意味を確認
*Person にすることで、構造体の中身を書き換えられる(mutable)ようになります。

「レシーバ付きメソッド」っていうのは
→ func (x T) MethodName() の形をした、「構造体などの型にくっついた関数」のこと
func (p Person) Greet() {
fmt.Printf("こんにちは、%sです!\n", p.Name)
}
type Person struct {
Name string
}
func (p *Person) Greet() {
fmt.Println("こんにちは、", p.Name)
}
func main() {
p := Person{Name: "太郎"}
p.Greet()
}
レシーバメソッドの補足
- Person という型(構造体)から、p という変数を作っています。
- このステップで「太郎」という人物を用意してるイメージ。
p := Person{Name: "太郎"} // ← ① 構造体の変数(インスタンス)を作る
- ①で作った p に対して、Greet() メソッドを実行しています。
- 「pよ、あいさつしなさい!」という命令。
p.Greet() // ← ② その人にメソッド(挨拶)をさせる
値レシーバ((p Person)
)との違い
func (p Person) Greet() // 値レシーバ(コピーを受け取る)
func (p *Person) Greet() // ポインタレシーバ(参照を受け取る)
レシーバ | 中身を書き換えられる? | コピー発生? | 主な用途 |
---|---|---|---|
値 | ❌ できない | ✅ する | 読み取り専用で軽い構造体向け |
ポインタ | ✅ 書き換え可能 | ❌ 発生しない | 大きな構造体・更新したい時 |