いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-225 (ジェネリックなビットフラグ処理)

概要

以前にビットフラグについて、以下のような記事をアップしました。

devlights.hatenablog.com

Go 1.18 からジェネリックが導入されたので、このような処理が汎用的に書けるようになりました。

てことで、ちょっとしたサンプルです。今回の内容は以下の情報を参考にさせてもらいました。

dev.to

サンプル

package bitflags

// Has -- 指定したビットが立ってるかどうかを返します。
func Has[T ~int](v T, flag T) bool {
    return v|flag == v
}

// Unset -- 指定したビットを落とします。
func Unset[T ~int](v *T, flag T) {
    *v = *v &^ flag
}

// Force -- 指定したビットで上書きします。
func Force[T ~int](v *T, flag T) {
    *v = flag
}

// Set -- 指定したビットを立てます。
func Set[T ~int](v *T, flags ...T) {
    if len(flags) == 0 {
        return
    }

    for _, flag := range flags {
        *v = *v | flag
    }
}

テストコード

package bitflags_test

import (
    "testing"

    "github.com/devlights/gomy/bitflags"
)

type _Flag int

const (
    Bit1 _Flag = 0b0000_0001
    Bit2 _Flag = 0b0000_0010
    Bit4 _Flag = 0b0000_0100
    Bit8 _Flag = 0b0000_1000
)

func TestHas(t *testing.T) {
    // Arrange
    sut := Bit2

    // Act
    result1 := bitflags.Has(sut, Bit1)
    result2 := bitflags.Has(sut, Bit2)

    // Assert
    if result1 {
        t.Error("sut has Bit1")
    }

    if !result2 {
        t.Error("sut does not have Bit2")
    }
}

func TestSet(t *testing.T) {
    // Arrange
    sut := Bit1

    // Act
    bitflags.Set(&sut, Bit2, Bit4)

    // Assert
    if !bitflags.Has(sut, Bit2) {
        t.Error("sut does not have Bit2")
    }

    if !bitflags.Has(sut, Bit4) {
        t.Error("sut does not have Bit4")
    }
}

func TestSetEmpty(t *testing.T) {
    // Arrange
    sut := Bit1

    // Act
    bitflags.Set(&sut)

    // Assert
    if !bitflags.Has(sut, Bit1) {
        t.Error("sut does not have Bit1")
    }
}

func TestForce(t *testing.T) {
    // Arrange
    sut := Bit1

    // Act
    bitflags.Force(&sut, Bit2)

    // Assert
    if bitflags.Has(sut, Bit1) {
        t.Error("sut has Bit1")
    }

    if !bitflags.Has(sut, Bit2) {
        t.Error("sut does not have Bit2")
    }
}

func TestUnset(t *testing.T) {
    // Arrange
    sut := Bit2
    bitflags.Set(&sut, Bit8)

    // Act
    bitflags.Unset(&sut, Bit2)

    // Assert
    if bitflags.Has(sut, Bit2) {
        t.Error("sut has Bit2")
    }

    if !bitflags.Has(sut, Bit8) {
        t.Error("sut does not have Bit8")
    }
}
gitpod /workspace/gomy (master) $ go test -cover github.com/devlights/gomy/bitflags
ok      github.com/devlights/gomy/bitflags      0.002s  coverage: 100.0% of statements

以下にコードはアップしています。

GitHub - devlights/gomy: This package is a personal library for Go language.

参考情報


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。