Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Go1.10と1.11は独自型で値を制限できないから気をつけて

More than 1 year has passed since last update.

昨日、バグを踏んでしまったので記事にしておきます。アドベントカレンダー空いてたし。
Twitterにも以下のようにアップしています。

きちんと説明してみる

例えば以下のような処理があるとします。

package main

import "fmt"

type MyString string

const (
    YES      MyString = "yes"
    NO                = "no"
    DONTKNOW          = "i dont know"
)

func foo(arg MyString) {
    fmt.Println(arg)
}

func main() {
    foo(YES) //success, prints "yes"

    foo("jop") //fails to compile
}

https://t.co/goaBEtg71L

MyString は独自型です。取りうる値は、YES, NO, DONTKNOWの3種類です。
fooの引数はMyStringなので、YESは正常に動きますが、jop はただのstringなのでコンパイルエラーを起こします。
これが正しい処理で、いままでもそのように動いていました。
この処理が正しく動いてる環境においては、独自型で取りうる値を制御できるので、引数の値をバリデーションする処理は不要です。

ですが、 1.10 もしくは 1.11 を動かすと以下のような結果になります。

yes
jop

jopが返ってきてしまっています。これは正しくありませんね。

もう一つ似たような処理を書きます。

package main

import "fmt"

type MyString = string

const (
    YES      MyString = "yes"
    NO                = "no"
    DONTKNOW          = "i dont know"
)

func foo(arg MyString) {
    fmt.Println(arg)
}

func main() {
    foo(YES) //success, prints "yes"

    foo("jop") //success, prints "jop"
}

https://play.golang.org/p/ah5qyFnoot_L

型指定のところが type MyString string だったところが、 type MyString = string になっています。
とても似ていますが、これはGo 1.9で導入された。 Type Alias と呼ばれる処理で、MyStringstringと同じ型として扱われます。
こちらに関しては、詳しく書かれている方がいるのでそちらを参照してください。

go言語1.9で追加予定の新機能 型エイリアス
https://qiita.com/weloan/items/8abbb4003cfa1031a9e9

こちらは、MyStringstringと同等ですので結果は

yes
jop

で、これが正しい結果です。

Goのリポジトリにもissueとしてあがっていますが、このType Aliasが問題を引き起こしているようです。
https://github.com/golang/go/issues/26390

問題はすでに修正済みで1.11のマイルストーンとして解決しているようです。
ですが、このようにも記載されていました

the real fix is slated for 1.12
-- 実際の修正は1.12に予定されています

1.12.1 では、直ってなさそうです

結論

1.10及び1.11では独自型で値の制限はかけられません。
値を制限したい場合はバリデーション処理を独自に作ってください。

usk81
お仕事内容:プログラマ & たまにインフラ & SEOラングラー & データアナリスト & データサイエンティスト見習い & バリスタじゃないけど、コーヒー淹れる人 & 農家から買い付けて日本茶淹れる人
https://usk81.dev
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away