2020/02/11

[golang]go runの引数はなんなのか

実は、今ひとつgolangの基本的なことが分かっていない。

importで指定しているあれはなんなのか? や、go runの引数はなんなのか? ということすらもだ。

 

では、今はどうやって指定しているかというと、なんとなく、だ。
エラーになったら違う文字列にしてみよう、くらいで、あまり考えていない。
さすがにこれはまずい。。。

 

importも気になるのだが、今回はgo runだけにしておこう。


go runの引数。

--helpを見ると、こうだった。

usage: go run [build flags] [-exec xprog] package [arguments...]

はい、packageですね。

 

しかし、だ。

src/ex1/ex1.go

01: package main
02: 
03: import "fmt"
04: 
05: func main() {
06: 	fmt.Printf("Hello\n")
07: }
    

golang/src/ex1 $ go run ex1.go
Hello

ほら、ファイル名でも通るじゃないか。
むしろ、

golang/src/ex1 $ go run main
package main: cannot find package "main" in any of:
        /usr/lib/go-1.13/src/main (from $GOROOT)
         /home/ueno/golang/test/src/main (from $GOPATH)

mainパッケージを指定した方がエラーになるくらいだ。

つまり、mainパッケージはパッケージ名ではない、ということか?

golang $ go run src/ex1/ex1.go
Hello

$GOPATHからのファイルパスを直接書いても通る。

golang $ go run ex1
Hello

かと思えば、ディレクトリ名でも通る。

では、packageを変えてみる。

src/ex1/ex1.go

01: package main
02: 
03: import "fmt"
04: 
05: func main() {
06: 	fmt.Printf("Hello\n")
07: 	fmt.Printf("%s\n", sub())
08: }
    

src/ex1/ex1sub.go

01: package main
02: 
03: func sub() string {
04: 	return "Sub"
05: }
    

どちらもmainだ。

 

golang/src/ex1$ go run ex1.go
# command-line-arguments
./ex1.go:7:21: undefined: sub

ふむ、1つしかファイルがない場合は特例として認める、というところだろうか。
同じディレクト入りにmainパッケージのファイルが複数あっても、ファイル名を指定すれば良いというわけだ。

 

golang/src/ex1$ go run ex1sub.go
# command-line-arguments
runtime.main_main·f: function main is undeclared in the main package

エントリポイントがないファイルはダメ、と。

 

golang/src/ex1$ go run .
Hello
Sub

ディレクトリを指定したのと同じことか。

 

golang/src$ go run ex1
Hello
Sub

golang$ go run ex1
Hello
Sub

うーん、ディレクトリというよりも、srcの下をたどる?

 

golang$ go run src/ex1
package src/ex1: cannot find package "src/ex1" in any of:
        /usr/lib/go-1.13/src/src/ex1 (from $GOROOT)
        /home/xxx/golang/src/src/ex1 (from $GOPATH)

srcはパッケージ名の一部ではない、と。

 

えーい、正解を見よう。

https://golang.org/cmd/go/#hdr-Compile_and_run_Go_program

> Run compiles and runs the named main Go package.

パッケージ名というよりは、mainパッケージを含んでいるパッケージを指定する?

 

> Typically the package is specified as a list of .go source files from a single directory, but it may also be an import path, file system path, or pattern matching a single known package, as in 'go run .' or 'go run my/cmd'.

複数のgoファイルを含んだ単一のディレクトリ(importパス、systemパス)、パターンに一致する単一のパッケージなどが典型的だと。

 

パスでもいいからgoファイル名でもいいと言うことかな?
だいたい、エントリポイントはmainパッケージに置くものだから、パッケージ名限定にできるはずがなかったな。

しかし、使いやすくしようとして、返って分かりづらくなっただけのようにも感じる。
いっそのことJavaみたいにディレクトリ階層がpackageになっていてmainパッケージが必須じゃない方があきらめがついたかもしれない。

ディレクトリの指定を許可するなら、相対パスで書いてもよいようにすればよさそうだが、そこは推奨しないらしい。
でも、pkg/だったりsrc/だったりすると、なんだかもう訳がわからないのよねぇ。

 

golangに文句があるというよりは、ルールがよくわからないので解釈に困っているというところだ。
バージョンの最初の方から使っていたら理解しやすかったのだろうか。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。