Goで空の構造体を使おう!!

Go言語

Goで空の構造体を使ってますでしょうか?
空の構造体を使うことでメモリ効率よくチャネルやmapの処理が使えることがあるため、便利な使い方について解説をしていきます。

空の構造体とは?

空の構造体はフィールドを持たない構造体のことで、サイズが0バイトです。
空のインターフェースでも良いのではと思われますが、空のインターフェースのサイズは16バイトになっています。

空の構造体と空のインターフェースのサイズの確認コード

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var s struct{}
	var i interface{}
	fmt.Println(unsafe.Sizeof(s))
	fmt.Println(unsafe.Sizeof(i))
}

実行結果

 % go run main.go 
0
16

実際にどういう所でこの空の構造体が使えるか、説明をしていきます。

map

例えば複数取得した部署のコードが被ってないか確認をしたい時に、mapを使ってO(1)で取得できるようにしますが、mapのバリューには特に値が入っている必要がないので、空の構造体をバリューにすることでメモリ効率をよくできます。

サンプルコード

package main

import "log"

func main() {
	nums := []int{1, 2, 3, 4}
	maps := make(map[int]struct{})
	for _, num := range nums {
		if _, ok := maps[num]; ok {
			panic("duplicate number found")
		}
		maps[num] = struct{}{}
	}
	log.Println("完了")
}

実行結果

% go run main.go 
2024/03/26 16:15:17 完了

チャネル

チャネルで通知が来たことだけを伝えたい場合は、空のチャネルを使うことで、メモリ効率が良くなる。

サンプルコード

package main

import (
	"log"
	"time"
)

func main() {
	log.Println("開始")
	ch := make(chan struct{})

	go func() {
		time.Sleep(1 * time.Second)
		ch <- struct{}{}
	}()

	<-ch
	log.Println("終了")

}

実行結果

% go run main.go 
2024/03/28 17:16:24 開始
2024/03/28 17:16:25 終了

参考

Go言語 100Tips ありがちなミスを把握し、実装を最適化する

まとめ

今回は空の構造体の便利な使い方について解説をしてきました。
他にもGoについての記事も書いておりまして、そちらも見ていただけたらと思います。チャネルについてよくわからないなという方向けに解説をしている記事もあります

【おすすめ記事のリンク】

コメント

タイトルとURLをコピーしました