Diverse Advent Calendar の9日目です。
普段 gitlab を使っていて不便なことがあったので解決するために golang を1日で勉強した話です。
他にも新しい言語を覚えよう、というときに応用が効きそうなので、まとめてみることにしました。
覚えたいこと
- golang の基本文法
- とりあえず cli ツールを作りたかったので、最低限
- 外部パッケージの使い方は知っておきたい
- goroutine とかは無しで
スペック
人間の。
- 使える言語(とそのエコシステムを知っている言語)
- Java, Kotlin (Maven (Gradleで使ったことがあるだけ))
- JavaScript (npm)
- Ruby (gem)
- Python (pip)
- C
- とか
- ポインタは C で散々やったのでわかってる(つもり)
できごと
弊社ではプロダクトのコードを管理するのに gitlab を使っていて、コードレビューも行っています。
動作確認などで手元に checkout してくる必要がありますが、 Merge Request (github で言うところの Pull Request) のページから対象ブランチ名をコピーしてくるのが面倒くさい…
そこで社内 Slack で聞いてみました。
「 git lab request
とかでプロジェクトのマージリクエストの一覧出せたりしないんですかねぇ」
「アドベントカレンダーのネタになるね!」
「APIあるで」
「はやいものがちだ」
(ファッ)
言語は指定されませんでしたが、オフィスを見渡しても使っている OS がみんなバラバラ(Mac, Linux, Windows)。
どうせ作るならなるべく多くの人に使ってもらいたいので、ほとんど触ったことがなかった golang で作ってみることにしました。
クロスコンパイルが簡単らしいという話は聞いていたので。
この機能は他の言語のアレ
"in other words" と言い換えていくパターンです。
そういう風にして覚えました。
引き出しの多さは、新しい知識の吸収を楽にしてくれるらしいので。
"golang は better C" という話は聞いていたので、とりあえず C 言語の親戚だと思って書き始めました。
注目したのは以下の箇所です。
golang では | あれだよ、あれ |
---|---|
ポインタ | Cと同様 |
メモリ解放 | GCがある。Java や LL と同様に気にしなくて良い |
テータ型 | C と同様のプリミティブ値、構造体、配列 + マップ、スライス |
戻り値が複数 | Python でタプルとして値返すのと一緒。_ で値を捨てられるのは Haskell っぽい |
アクセス修飾子 | Java っぽいアクセスコントロール。 修飾子はないが、 lowerCamelCase で private、 UpperCamelCase で public |
クラス | ない。特定の構造体が使える関数は定義できる。 JS の prototype に多少似ている |
スライス | 扱い方は Python のスライスと似た感じ C の配列(配列型変数)に近いが多少違うらしい |
変数宣言 |
:= で Kotlin っぽく型推論してくれる。型の指定も Kotlin とかっぽく後置 |
外部パッケージの利用 | npm (install -g) や gem らしく go get (パッケージID) でインストールしておけば、 import で使える |
「この問題、○研ゼミで見たやつだ!」と思ったら違ったところ
他の言語と同じように考えて使っていたらそうではなかった、という部分もありました。
頭のなかにある既存のモデルと異なるので、言い換えが効きません。
こういうところが、新しい言語を覚える上で「詰まるところ」なのでしょうか。
今回はひたすら Google 先生に質問しまくって理解しましたが、良い乗り越え方があれば知りたいところです。
未使用変数や未使用 import 宣言があるとコンパイルが通らない
他の言語だと問題なく通るので、最初はびっくりしました。
びっくりしたくらい。
go run main.go とすると別ファイルに書いた変数や関数を参照できない
go run *.go
としないと動かないそうです。
(後から考えてみれば、リンクするオブジェクトファイルの中から関数などを探すわけですから当たり前っちゃ、当たり前ですね…)
そもそも import 文に使用するファイル名とか書かなくても良いのか? と思っていたら、どうやら golang では同じパッケージに含まれるものは特別に宣言がなくても使えるらしい。
だからと言って、以下のように main()
だけ含まれるソースを go run
の引数に指定しても動かないようです。
LL を走らせるのと同じ感覚でいたので、これがどうして動かないのかわからず、しばらく困っていました。
勝手に他のソースコードを見に行ったりはしてくれないようです。
go get = npm (, gem, maven) ではなかった
go get
すると、依存関係を解決しながらライブラリやアプリケーションを GOPATH に突っ込んでくれるので、 npm や Maven と同じ感覚で使えるだろうと思っていたら、多少違いました。
GOPATH 内ではローカルパッケージが使用できないらしく、不用意にディレクトリを掘れません。
だから github に上がっている golang リポジトリは、リポジトリルートに go ファイルがずらっとなんでいるのかな、とも思いました。
上手い解決方法があったら教えて下さい。
そうしてできたものがこちらです。
コンソールから gitlab の様子を見られるので、わざわざブラウザを見なくて良くなります。
git-lab - yet another git-lab command
こんな風にして一日で新しい言語覚えてみた、という話でした。
「こういう考え方で勉強したほうが捗るよ!」
「自分はこうやって勉強してるよ!」
などありましたら、教えていただけると幸いです。