LoginSignup
15
8

More than 5 years have passed since last update.

Go言語のblank typeとblank function

Last updated at Posted at 2016-10-19

ブランク

Golangにはブランク識別子というlinux系のdev/nullのようなダミーの識別子があります。

有名な使い方としては
多値の戻り値の内、不要なものだけ捨てるblank variableと
Databaseドライバを使う時などのinitだけを使用するblank importの二つだと思います。

package main
import (
    _ "github.com/gopher" //gopherは無に吸い込まれ、initだけが我々の心に残る
)

func main(){
    gopher,_ := MyName() //errは無に吸い込まれ、不具合として再び我々に立ちはだかる
    _ = gopher //テスト時とかにコンパイルエラーを起こさないように使ったふりだけする
}
func MyName()(string,error){
    return "gopher",errors.New("致命的なエラー")
}

しかしブランクはそれだけではありません。

ブランク型とブランク関数

実はこのブランクはタイプや関数の宣言でも使えます

package main
import "fmt"

type _ struct{
    gopher string
}
type _ int //二つ目を宣言してもコンパイルが通る

func main(){
}

func _(){
    fmt.Println("I am gopher.")
}
func _(){
    fmt.Println("We are gopher.")//こちらも同様
}

これが何に使えるかというと
残念ながら糞ほどにも使えません。

ただblank functionの方は
go内でgoto文のテストなど、goそのものの構文のテストのために使われています。
文法だけチェックしたいという時には確かに使えますが
そんな機会は普通のプログラマには訪れないというかこんなまどろっこしいやり方をする必要はないので
まず役には立たないでしょう。

blank typeを使ってるところは探したらあるかもしれませんが見たことないです。

存在理由

こうなるとなぜこんなことが出来るのか不思議ですが
Golangの長所として可読性のための一貫性によるものだと思います。
こういった細かいところまでブランクとして働いてくれるおかげで
blank importもblank variableもそれぞれ独立した機能でなく
"_"自体をブランクとしての役割と強く認識できます。

識別子の機能を可能な限りもっともな振る舞いをさせることで
この言語はblankとfunctionはOkだとかvarとconstは一括宣言できるだといった組み合わせを単に暗記するのではなく
ブランクならあれもできるだろうという推測でプログラミングが出来るようにすることで
一々文法をチェックする手間もなく、学習を容易にしてくれているGolangの気遣いの副産物だと思います。

普通の言語ならコンパイラ的にblank importやblank variableとは構文が全然違うので
出来ないだろうと察してしまうものだと思いますがその必要はありません。
なんかあの、ゲームでドアのテキスチャが壁のテキスチャと一体化してるからこれは開けないドアだなとか
運転免許の試験で何々してはいけないとかいう選択肢はまず間違っているだろうなとかいう
我々が現実社会で培った卑しくあさましいメタな視点は必要ないんです
ドアだから開くしブランクだから無効化してくれるんです。素晴らしいですね。
指数的に増えていく組み合わせは覚える必要ないんです。ただ一つブランクを覚えるだけで済むんです。素晴らしいですね。

ブランク小ネタ

他の使い方としては
インターフェース等の都合で
関数の引数や戻り値を指定するときに使わないと分かっている変数をブランク

func (devnull) Write(p []byte) (n int, _ error) {
    n = len(p)
    return
}

かなり低レベルな処理でしか使わないと思いますが、
構造体のメンバ変数にブランクを追加してpaddingもスマートにできます。

package main
import(
    "fmt"
    "unsafe"
)

type Girl struct{
    _ [100]byte
}

func main(){
    const size = unsafe.Sizeof(Girl{})
    fmt.Printf("%vkg",size) //100kg
}

iotaをブランクで進めるなども

const (
    Prime1 = iota
    _,
    Prime3
    _,
    Prime5
)
15
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
8