python→Go言語と学んだかけだしエンジニアの日記

# 閲覧の注意点
かけだしエンジニアの所感を書いているのみになります
技術的な得るものは少ないでしょう

# 私の経歴
2013年大学卒業、製造業へ入社
2013年～2019年　生産技術系のエンジニアとして全くプログラミングとは関わらずに過ごす
2020年　生産ラインでpythonを使ったＡＩ画像検査のプロジェクトリーダーとなる(自分ではコード書かない)
　　　　自分でコード書かないため、勉強もチュートリアルもすぐに挫折する
2021年　仕事でも使い始める(主にVBAの代替として色々、、、可視化、自動化、分析など)
　　　　プログラミングに興味が出てきて業務とは別にプライベートの時間でkaggle、競プロなどにも取り組む
2022年　とある業務効率化でpythonを使う必要が出てくる
　　　　データベースや画像検査、Webスクレイピングなどを学ぶ
　　　　年末にコロナ罹患、Go言語学習を開始する
　　　　Udemyで酒井潤さんの[現役シリコンバレーエンジニアが教えるGoで始めるスクラッチからのブロックチェーン開発入門](https://www.udemy.com/course/go-blockchain/)
　　　　などを学ぶ。その他多数
　　　　
　　　　業務でGo言語を用いたプロジェクトスタートし、プロダクトオーナー的な立場になる（自分でしっかりコード書く。GCPなどのクラウド構築も）

*IT業界の方は驚愕かもしれませんが、製造業ではちょっとIT詳しいらしいという理由でプロダクトオーナーになります。プロマネも兼ねる場合が多いですが、SIerに丸投げというのも多いです。


現在の私の状態：pythonとGoが両方基本的な内容が書ける状態

# python⇔Goの言語使用の差
|内容|python|Go|
|----|----|---|
|実行|インタープリタ|コンパイル|
|型定義|動的|静的|
|並列処理|GILがあって難しい。出来ても遅い|goroutine神|
|用途|機械学習、Webスクレイピング、バックエンドなど多岐にわたる|バックエンドがメイン|

# pythoとGo言語の差
python →インタープリタ
Go　→　コンパイル
なので明確に違いがあり、実行速度の差を生んでいる。

初学者にとってはコンパイルの意味が分からないし、コンパイル時にエラーが発見されやすいので
「え、エラー出た意味わからん」となりコンパイル言語が億劫に感じると思う。

例えばHello Worldを行おうとすると
python
``` python
print("Hello World")
```
で
Go
``` Go
package main
import("fmt")
func main(){
    fmt.Println("Hello World")
}
```
と記述量に大きな差が出る

また機械学習やデータ分析を行う場合、大量データの読み込みなどの処理には時間がかかるため
変数として置いておき、何度もトライ＆エラーを行うようなことが多い
こういった場合には1行1行実行できるjupyterの環境が最適と感じる


ただある程度エラー処理に慣れてくるとコンパイル時に
- 使っていない変数をエラーとしてはじいてくれる
- 型定義が間違っていると教えてくれる
- 文法が間違っていると教えてくれる
というのは本当に便利である。
1年前に書いたpythonコードは本人から見ても意味不明だけどGoならコメントなくても大体わかる。

これはGo言語の素晴らしい開発体験の1つだ。

## pythonとGoのエラーハンドリング
pythonでは基本的にエラーハンドリングをしなくても動くコードが作れてしまう。
これは大きな弊害を生む。
開発者のレベルによって動作の安定性が全く異なる点だ。
組織としてエラーハンドリング方法やwikiなどを効率的に運用出来ればいいが、
それは組織に依存する形になる。

組織的にコードの管理や運用方法が落とし込めていない業界では
すべては組織依存≒人依存だ

「〇〇社の△△さん転職したらしい」となればコード・製品の再現性が完全に消失する。

ここでpythonを用いた製品なんかを扱っていると悲惨な目になる。
わからないのだ。何もかも。
例えばモジュールで
t.t_.do(a) ※引数aが再帰が複数あるリスト
というモジュールが完成品コードの中に入っている状態で納品されていたりする。


一方Go言語では関数の型定義必須だし、基本的な関数やモジュールにerrが返り値として
格納されている。
エラー起きたらどうする？という課題を先送りにできない。

「簡単な変数を作るだけなのに型を明記しなきゃいけないの面倒だよ～」
という文句が聞こえてくるが、そういう人には以下の回答をして結語としたい。

(t.t_.do(a)というモジュールを改変しなきゃいけない立場にした上で)
「どちらが良かったかな？」


## 並行処理と実行速度、動作の安定性
色々な人が記事で書いているがGo言語の動作速度、実行時のメモリ消費量などは
pythonと比較すると雲泥の差である。(需要があればいずれ記事に書きたいと思います)


また並行処理に関しては
pythonの場合concurrent futuresやjoblibなどから要件に応じて選択する必要があり、誤った使われ方をすると
シングルスレッドよりも遅くなる。
というよりほとんどの場合オーバーヘッド時間の長さの関係で動作処理は遅くなる。
pythonの場合基本的にはIOやAPI呼び出し待ち時の待機処理専用と考えていい

一方Go言語の場合、
goroutineという便利な並行処理ツールがデフォルトでついており、
・簡単な記述(頭にgoつけるだけ)
・少ないオーバーヘッド時間
・驚異の低メモリ消費
を実現している。
wgやchanなどを併用することで変数の受け渡しや合流も思い通りに記述できる

## 開発体験
ごめんよpython、ここはGo言語の方が圧倒的に良い

### モジュール管理編
pythonの場合
pyenv、conda、venv、pipのみ正面突破
などの方法があるが、どれもしっくりこない。面倒だ


Go言語の場合
```
go mod tidy
```
だけで大体いける。
ありがてえ

### コードフォマッタ編
pythonには公式のコードフォーマッタがない。
pythonはインデントによって意味が異なるため、インデントを適当に書いてはいけないような言語使用になっている

``` python
a = 0
for i in range(10):
    a = a + 1
    print(a)
```

と
``` python
a = 0
for i in range(10):
    a = a + 1
print(a)
```
では意味が異なる


Goだとfuncでもfor文でも{}によって閉じられる。
インデントは適当に書いても
go fmtでとてもキレイなインデント構成に整えなおしてくれる

``` Go
package main

import (
	"fmt"
)

func main() {
			a := 0
for i := 0; i < 10; i++ {
a = a + 1
								fmt.Printf("%v", a)
	}
}
    
```
と適当に書いても

``` Go
package main

import (
	"fmt"
)

func main() {
	a := 0
	for i := 0; i < 10; i++ {
		a = a + 1
		fmt.Printf("%v", a)
	}
}

```
このように自動的に整えてくれる。ありがとうねえ

## 総評
結論としてはGo言語って開発体験とてもいいよってこと
Go言語は実はオンプレ環境でよく使われているというのは上記の言語仕様の他にも
バイナリサイズが小さいなどの要因もある。

今後製造業でIOTを進めていく上でファーストチョイスとなる言語にになっていくのだろうか

各種モジュールメーカー、PLCメーカーさん、対応言語にGo言語追加してくださいね