Go

Go の Enum 表現

More than 1 year has passed since last update.

Terraform のプルリクをレビュー してもらっている時に、次のようなコメントをもらった。

+   resGroup := d.Get("resource_group_name").(string)
+
+   skuName := d.Get("sku")
+   sku, err := getSku(skuName)
+   func getSku(skuName interface{}) (*operationalinsights.Sku, error) {
    if skuName == nil {
        return nil, nil
    }
    skuEnum, err := getSkuNameEnum(skuName.(string))
    if err != nil {
        return nil, err
    }
    return &operationalinsights.Sku{
        Name: skuEnum,
    }, nil
}

こうなっているのを下記のように。


since we can just cast directly to the Enum, we can replace this with:

sku := &operationalinsights.Sku{
 Name: operationalinsights.SkuNameEnum(skuName),
}

てっきり、ゴリゴリ書かないと行けないと思ったけどいらんかった。確認してみよう。

Go の enum

Go では、Enum はないが、idiom としてこんな感じの様子。

type SkuNameEnum string

const (
    // Free specifies the free state for sku name enum.
    Free SkuNameEnum = "Free"
    // PerNode specifies the per node state for sku name enum.
    PerNode SkuNameEnum = "PerNode"
    // Premium specifies the premium state for sku name enum.
    Premium SkuNameEnum = "Premium"
    // Standalone specifies the standalone state for sku name enum.
    Standalone SkuNameEnum = "Standalone"
    // Standard specifies the standard state for sku name enum.
    Standard SkuNameEnum = "Standard"
    // Unlimited specifies the unlimited state for sku name enum.
    Unlimited SkuNameEnum = "Unlimited"
)

わざわざ、string を、SkuNameEnum というタイプに変更している。これにより、SkuNameEnum という型を定義して、なおかつ、続くconst によって、固定の値を定義している。

使ってみよう。

func main() {
    skuName1 := SkuNameEnum(Free)
    skuName2 := SkuNameEnum("Standalone")
    fmt.Printf(string(skuName1))
    fmt.Printf(string(skuName2))
}

実行してみる。

FreeStandalone

ちゃんと使える。この構文はよく考えたら型変換の、int("2") とかと同じ構文だ。キャストがしっかりできている。また一つ学んだ。