Go language part 5

■ このスレッドは過去ログ倉庫に格納されています
2022/02/27(日) 07:43:20.04ID:uWHjNeVw
Goについて扱うスレッドです。
GoはGoogleによって開発された言語です。

公式
https://golang.org

公式ドキュメント
https://golang.org/doc/

公式外パッケージドキュメント
https://godoc.org

ブラウザ上で試し書き
https://play.golang.org


※前スレ
Go language part 4
https://mevius.5ch.net/test/read.cgi/tech/1605467680/
2022/06/26(日) 21:48:32.78ID:n40xbeTi
カバレッジ100%目指さないの?
共通ライブラリのエラーのパスとか
2022/06/26(日) 23:06:38.35ID:yMoKMg46
別におすすめじゃないけどgomock使ってる
gomockはinterface{}だらけで静的型チェックが効かないからたまにイラッとする
2022/06/26(日) 23:08:45.74ID:yMoKMg46
間違えた
gomockじゃなくてtestifyだ
2022/06/27(月) 08:35:06.00ID:YooYWD1s
がーん、週明けで確認したらGCPでホストしているサービス二個ともが、のきなみサーバーエラー500で動いてない
Memorystore の障害なのか?これは
2022/06/27(月) 08:37:17.96ID:YooYWD1s
Firestoreのクエリ結果をキャッシュしてるから確かに使ってる
2022/06/27(月) 08:40:10.32ID:YooYWD1s
あ、よく考えたらGoスレではスレ違いな話題だったスマン
ホストしてるのはGoだけど
2022/07/02(土) 23:20:51.48ID:IZ1AfdFM
質問
xxxx_test.go は go test だけで、go build からは無視されるとかって本当?
だとすると package xxxx_test とかパッケージを分けるのって意味がない?
2022/07/02(土) 23:36:14.32ID:IZ1AfdFM
あー、テストで xxxx をインポートしてる別パッケージをインポートしたいときに、xxxx からじゃ循環参照としてコンパイルできないから意味はあるのか
2022/07/02(土) 23:50:10.91ID:WXVFk7BC
ごくまれに package xxxx_test を作ったほうが簡単に解決できることもあるね
2022/07/03(日) 08:48:25.27ID:7pvv3VrN
*bufio.Scanner とか *os.File といった、interface じゃなく struct な戻り値を返す標準関数で、scanner.Scan() とかの戻り値による分岐をカバレッジしたい

標準関数は関数ポインタによるフックに変更して、モックで差し替えられるようにしたんだけど、関数ポインタのシグネチャが struct を返す形なんで、上記の scanner.Scan() とかを差し替えられない

そこで bufio.NewScanner() を直接に使うのではなく、scanner を interface で返すラッパー関数を作って、そのラッパー関数ポインタをモックで置き換えさせることを考えたりしてるんだけど
…やり過ぎ?(そもそもこの説明で分かるかな?)
2022/07/03(日) 08:55:03.83ID:7pvv3VrN
そもそも例外なケースのカバレッジのために、そんなクソ複雑なメカニズムを入れるのは、保守性を下げてしまうから本末転倒だろうか?
2022/07/03(日) 11:51:42.83ID:l1HGgLKC
Go的には、差し替えが必要なんだったらScannerを直接使わずに最小限のアドホックなinterfaceを定義し、
それを関数の引数に受け取るかstructのメンバに持たせるのが筋
2022/07/03(日) 13:48:43.92ID:7pvv3VrN
>>448
うん、そんな感じ
https://pastebin.pl/view/d979ea5b
該当部分を抜粋
しかし無駄に複雑なコードかなぁと
そこまでする意義はあるのかないのか
2022/07/03(日) 13:59:46.67ID:7pvv3VrN
>>449
これだけ複雑なのに、os.Open() と s.Err() がエラーを返すパスを通せるだけというのは、
コードの保守性悪化に見合うメリットたりえるのか
そう感じてしまって悩んでる
これが Java ならクラスローダーでプロキシインスタンスに差し替えるという手段で対象コードには手を触れなくて済むから…
2022/07/03(日) 15:10:23.33ID:Z8jWnyOJ
>>450
そのへんはGo云々というより設計センスの問題だな
textLinesがhookを持つのではなく、LoadFromの引数にfilenameの代わりにiScannerを渡して、その実装を提供するのは呼び出す側の責任にした方が良いと思う
filenameを受け取る便利関数を提供したいなら、それとは別にLoadFromFileNameみたいな関数作ってFileやScannerをインスタンス化してLoadFromに投げればいい
そうすればインスタンス化の部分とそれを使う部分とでテストケースを分離できるでしょ
2022/07/03(日) 23:23:15.49ID:kM3791I8
そうだな、設計の話だなあ
コードがそこそこの規模になるんだったらとりあえずDI的なことをやったほうがいいよ
2022/07/10(日) 17:20:12.05ID:EjhmXdOb
普通に自前でScanner作れよ
大して難しい話じゃないだろ
454デフォルトの名無しさん
垢版 |
2022/07/11(月) 19:28:21.15ID:QgABBT19
構造体のコンストラクタのコードを見ると必ず構造体のポインタを返していますが、ポインタにするメリットと値を返したときのデメリットを教えて頂きたいです
2022/07/11(月) 20:06:52.63ID:BS7kt+k9
>>454
受け渡しの際に毎回コピーするのではなく同一のインスタンスを引き回すことを想定している場合、
それを利用者に主張するために値ではなくポインタを返すことが多い
ポインタで受け取ったものをわざわざデリファレンスしてコピーなんて普通あまりしないからね
構造体をオブジェクト指向言語におけるミュータブルなクラスのように使っていると、コピーされると意図せぬ挙動になりやすい
2022/07/12(火) 09:01:35.03ID:r0oulnz0
>>453
>>449 見れば分かるがファイル名を受け取ってos.Openして得たFileからScannerを作ってるわけで、これをどうやって差し替えるかという話
2022/07/12(火) 09:02:55.76ID:r0oulnz0
>>453
だから、ScannerではなくNewScanner関数をどう差し替えるかという話
458デフォルトの名無しさん
垢版 |
2022/07/12(火) 09:14:17.91ID:bpFuPlMn
>>455
よく分かりました
ありがとうございます
2022/07/15(金) 23:35:22.96ID:1DD1sO9i
コンパイルするファイル内に設定値も全部入れたいんだけど、
その場合は設定値だけのファイルを読み込むことって可能ですか?
関数にしてmapで返す感じしかないですか?
2022/07/16(土) 13:38:45.14ID:Gzq+vhF3
jsonファイルをgo-assetsとかgo:embedで組み込んで、それをjson.Unmarshal()で構造化データとして使えばいいと思うよ
2022/07/16(土) 14:06:11.73ID:F7RlRzGb
個人的には設定はビルド時に埋め込むならソース内にjson風にハードコードする派
設定ファイル嫌い
2022/07/17(日) 05:50:18.02ID:p7xubc+G
てめーの好き嫌いなんか知ったことじゃない
2022/07/17(日) 08:32:38.03ID:Em8OpVY9
組み込みjsonをデフォルトとして、カスタム設定ファイルは外部のjsonにする
デフォルトから取り込んでカスタムで上書き
これでjsonからの取り込み部分を一本化できるのでバグを防止できる
ハードコードしてると取り込み部分が共有できない (json文字列を返す関数でもいいんだけど
2022/07/17(日) 09:17:16.84ID:mx7kwKTp
>>463
組み込み設定は構造体をハードコードし、カスタム設定ファイルはそれをjson等で上書きすればいいだけ
どうせ上書きされるのは極一部の項目だけなんだから、大部分はコンパイル時のチェックによりバグを防止できる
2022/07/17(日) 19:27:05.51ID:Em8OpVY9
>>464
と、思っちゃうよな
構造体定義して、初期化で初期値書き込んで、それとは別にカスタム設定取り込みコードを書く
対して、構造体定義して、設定取り込みコードを書く
すると設定取り込みには普通にバリデートも書くから初期化での値バグが起きない
2022/07/17(日) 19:36:44.11ID:Em8OpVY9
>>464
まあ、好きずきの話に近いことは近い
ハードコードした設定値をバリデーターにかけてチェックさせる作りなら解決できなくもない
でも取り込みの各段階でバリデーションしていったほうがミスりにくいと俺は思うから
2022/07/17(日) 19:43:13.12ID:EABPDou+
そんなにバグが怖いならそもそもそんな柔軟な設定ファイル要る?というところを見直すべきでは
汎用的なOSSでも作ってるんでない限り、設定なんぞ環境変数で十分
あとは全部ハードコードすればバリデーションなんか要らん
2022/07/18(月) 09:02:04.30ID:unHGOtJd
バグが怖いというより、適切なアナウンスかな
設定のどこが、どう不味いのか
2022/07/18(月) 16:09:24.37ID:k+MW10XJ
Viperを使え
2022/07/21(木) 22:26:13.75ID:CXPkj94/
フレームワークのginでWebアプリ作りたいなと思ってるんですけど、ginの勉強にいい教材ありますか?
Pythonでツール作ったことあるくらいで、Goの基礎は一通りやったくらいのスキルです。

日本語ドキュメント見てもいまいちピンときてません
https://gin-gonic.com/ja/
2022/07/21(木) 22:30:02.68ID:2u+uMLjG
gin自体が良くないからいい教材なんか無い
Goはnet/httpパッケージを使うんだよ
2022/07/21(木) 23:21:18.30ID:CXPkj94/
そうだったのか。。
2022/07/22(金) 02:56:37.89ID:J1VsK1aI
いやGinでいいだろ
今どきnet/httpだけでWebアプリ作ってるとこなんてねーよ
Gin+Vueとかで作ってみな
5chにいる玄人()のおっさんに惑わされんな
2022/07/22(金) 03:45:47.87ID:GTjCaUbk
俺はchiがおすすめ
2022/07/22(金) 12:01:47.88ID:wu+YttEu
最近いじってないけど
Echoは少数派なの?
476デフォルトの名無しさん
垢版 |
2022/07/22(金) 13:57:48.11ID:sWmP1lOI
>>473
さんきゅー!
2022/07/22(金) 14:20:09.64ID:whw2xWQR
gin、chi、echoどれも薄っぺらいんだから対して変わらない
どれでもええわ
2022/07/23(土) 09:09:18.33ID:e1dxODSm
echo はcontext の扱いが良くない
2022/07/29(金) 12:06:04.77ID:Nm1LHugv
Fiberこそ至高
2022/07/29(金) 12:08:16.31ID:CmFCr4CU
月額報酬が最も高い開発言語ランキング 3位は「Python」、2位は「Go」、1位は? フリーエンジニア向け仕事仲介サービス調べ
2022/07/30(土) 02:29:49.54ID:Wzbfhtrr
URLを貼らないあたり仕事できなさそう
2022/07/30(土) 05:26:38.23ID:fJ4AJJUc
Goは単価高いけどGoだけ出来ればいいってわけじゃないからなぁ

ECSとかTerraformみたいなクラウド技術も使えて当然だよね?って雰囲気が全体的にある
2022/07/30(土) 17:20:05.92ID:wZaxY20D
Goのmapをfor分で回すと順序が不定というのはなんでそうなったの?
2022/07/30(土) 17:42:37.40ID:54mLdGPJ
>>483
将来的な最適化の余地を確保するため。
大抵の言語では、標準のハッシュ表はその内容が変更されない限りは順序が変わらないような実装がなされていることが多い。
しかし、プログラマにそれを期待したコードを書かれてしまうと、内容が変わらなくても順序が変わりうるような実装に将来的に変更したときに既存のコードが破壊される可能性がある。
Goはそれを避けるために順番を意図的にシャッフルしている。
例えば、将来的にはGCがmapのメモリレイアウトを自動的に最適化するかもしれない。仮にそうなればプログラマが内容を変更したつもりがなくても順番が変わるだろう。
2022/07/30(土) 18:14:58.42ID:wZaxY20D
>>484
なるほど
意図的にやってるのか・・・
2022/07/30(土) 23:59:57.16ID:H9aJG6PT
Rubyとかは逆に不定じゃなくしたよね。いつだったかのタイミングで。

あれは変な判断だと思ったなぁ。
2022/07/31(日) 00:35:32.67ID:FStFDS54
Rubyの連想配列(Hash)にはshiftっていう変テコなメソッドがあるせいかなあ
2022/07/31(日) 00:47:08.11ID:tsdyYOt0
RubyやPythonの用途なら挿入順でイテレートできるようにするためにかかるコストよりも
利便性が優先されるからじゃないかな
489デフォルトの名無しさん
垢版 |
2022/07/31(日) 02:02:03.13ID:fu2FWHQK
ですな。
2022/08/03(水) 10:05:50.52ID:pR7q6wnw
Go 1.19 is released!
https://go.dev/blog/go1.19

もう出た
今verは早かったな
2022/08/03(水) 12:30:49.23ID:HH6IlM8W
Pythonはordered dictがいつの間にか標準dictになってたな
便利だからいいけど
2022/08/09(火) 14:19:29.00ID:/hRQdNQg
最近の言語仕様書はDeepLすら受け付けない英文なのはどうにかしてくれんかな
ほかにもインターフェース関係の解説でいつの間にか話に出てきてないFileインターフェースが混じってきたり
絶対にレビューしてないよな

なお1.17を読んでる(1.18 からはジェネリクスで更に混迷が進んでる)
2022/08/18(木) 10:59:30.64ID:uJ4JpjWj
ふと

channel はチャンネルと読んでる?チャネルと読んでる?
2022/08/18(木) 12:00:31.81ID:I3eJj73g
チャネル
2022/08/18(木) 12:23:20.11ID:cEC5FUVy
正確な発音はチャノォ
2022/08/18(木) 13:07:53.85ID:nV24tQaO
んゅにぇぅな?
2022/08/18(木) 14:36:09.80ID:wr3YJ4Iv
茶野ぉ?
2022/08/18(木) 16:47:44.68ID:sstdM9KK
チャノルなぞ使わん!
男は黙って共有&mutex
499デフォルトの名無しさん
垢版 |
2022/08/20(土) 04:18:43.73ID:O8Vd08Ya
>>473
ginのルーティングが糞なのは直ってるの?
2022/08/20(土) 08:17:30.29ID:9Gwmc6Wf
実際goをつかいはじめのころはチャンネルの仕様とか使いかたとか調べるのが面倒で
勝手しったるmutexばっかりつかっていた
2022/08/20(土) 08:27:18.78ID:jhGGjByr
よーわからんし、echoで問題ないから使ってる
502デフォルトの名無しさん
垢版 |
2022/08/20(土) 11:47:33.07ID:O8Vd08Ya
俺もecho
2022/08/20(土) 23:47:54.29ID:McSzx8ex
gin → beego → echo → chi イマココ
2022/08/30(火) 15:48:26.25ID:F+/knOGo
言語仕様書の1.17を底本として翻訳してるんだけど、文書的に酷い(~;~の使いすぎが特に…)し、構成的にもクソだなぁ
underlying type に関係した性質なんて文書全体を読まんと把握できないわ

メソッド式の話では、ポインタによるレシーバーのメソッドは値による呼び出しは出来ないとか書いてあるけど、レシーバー宣言が値だろうがポインタだろうが、現行じゃ問題なく呼べるようになってる(更には値でセレクタ呼んでもポインタで呼んでも動く
つまりどこかで仕様が拡張されてるのに、仕様書は更新されてないっぽい疑惑
2022/08/30(火) 15:50:42.61ID:F+/knOGo
仕様書なんて熟読しなくても、フィーリングで書いて動いちゃうから、今まで気にしたこともなかったし
気にしなくても動くんだからいいじゃない?とも思いはする
2022/08/30(火) 22:31:49.83ID:1po1mIkW
そんないいかげんな感覚で思い付きどんどん拡張したその結果が今のC++のていたらくだ!!
反省しなさい!
2022/08/31(水) 00:35:38.08ID:Pib5lp7c
C++があんなことになったのはむしろ、C++プログラマたるもの仕様書くらい熟読しているだろうと開発陣が高を括ってきた結果だろう
2022/08/31(水) 10:19:04.29ID:3xNaBMUA
あんなブ厚いARMを読むなんて苦行が過ぎる
悟りに至りかねない危険な行為だ
2022/08/31(水) 12:04:18.42ID:3xNaBMUA
あるえー?
仕様書で終了ステートメントに続くステートメントに関する記述が無いんで、Playgroundでmainの最初にreturnを書いたらコンパイルエラーにならんかったし実行時エラーも起きない
到達不能ステートメントはチェックされないんだな
2022/08/31(水) 12:08:28.43ID:rT6IO02J
そもそも規格化されてる言語じゃないし、コミュニティが用意した言語仕様書にそこまで大きな意味はないんじゃないの?
仮に処理系と内容が違っててもどっちのバグなのか第三者にはわからないこともあるだろう
2022/08/31(水) 14:11:42.15ID:LHsSKudI
いかにも仕事が雑なグーグルらしい雑な仕様の言語
2022/08/31(水) 15:08:28.04ID:ZrN/2uvg
そうか?Googleの割にはまともだったから普及したんだと思うぞ
いつものGoogleはWeb系のノリで言語作るからこんなもんじゃない、そして大コケする
2022/08/31(水) 16:28:21.64ID:wsiOIOpJ
Rustほど初心者が書きにくくはないし
PythonやRubyよりは確実に速い
ちょうど良いところを付いたと思うよ
2022/08/31(水) 17:49:58.71ID:QWrElnZY
だがバグらないために気を付けないといけないことが多い
2022/08/31(水) 18:35:42.76ID:rT6IO02J
なんかしらんけどGoがしんどいなら使わなくてもいいんだよ
2022/08/31(水) 20:53:39.37ID:3xNaBMUA
バグらないために気を付けなきゃならんことなんて、他の言語に比べるとそんなに多くないだろ
2022/08/31(水) 21:04:49.54ID:v1Af5w53
100 Go Mistakesを読むといいよ
2022/09/01(木) 09:53:36.13ID:dbQKPphW
言語設計でしくじってるよなぁと思うのは、構造体の生成回りの構文というか思想
Cに引っ張られ過ぎてて生成の基本が実体を作ることになってる
構造体はデフォルトでアドレスとして出現し、Javaとかのように参照と命名しとけばよかった

そうすればスライスとかマップのイテレーションがクソみたいな落とし穴にならないし、マップをインデックス式でアクセスしてセレクタとしてフィールドにアクセスも出来るようにできた

実体を使いたい場合は*でデリファレンスして使う
実体ちゃんの変数も*Tという型とする
実体配列は[]*Tという配列を記述するようにする

*に関しては、レシーバーとか宣言で(r *T)とかデリファレンス演算子をポインタを示す記号に使うような一貫性のなさも解消する
プリミティブな変数が実体で、そのアドレスを&で取得するということからの一貫性に拘ってるんだろなぁ

実体配列なんて、Dockerの管理用配列以外で見たことないよ…少なくともレアな宣言だと思う
2022/09/01(木) 11:44:46.07ID:8wwpfCzj
欠点を挙げる流れだ
やっぱ入れ子の構造体の初期化でしょいかんよあれは
2022/09/01(木) 12:50:03.20ID:cWwvmbGP
この辺の問題が起きないようにしっかり対策取ってる?
https://www.uber.com/blog/data-race-patterns-in-go/
https://blog.acolyer.org/2019/05/17/understanding-real-world-concurrency-bugs-in-go/
2022/09/01(木) 12:54:11.77ID:dbQKPphW
複合リテラルとして書けばいいんだし、落とし穴的な問題はなくない?
俺は悪くないかなと思ってるんだけど
2022/09/01(木) 13:00:51.78ID:dbQKPphW
>>520
「これらの多くは、チャネルでの送信または受信の欠落、またはチャネルの閉鎖が原因です」
いや、mallocしといてfreeしてませんでしたレベルの話をされてもどうしろと?
普通に対策考えないでプログラミングなんてできないだろ
2022/09/01(木) 14:02:59.57ID:dbQKPphW
>>518
ポインタを示す型なら&を使ってT &pにしてデリファレンスは*p
とか実際に書いてみたら物凄い違和感に襲われてしまった

…C言語の呪いって凄いわ
2022/09/01(木) 14:17:02.40ID:3zc//kWQ
>>522
それってプログラマー任せのノーガード戦法ってことでしょ?
リストアップされてるような各種バグに対してシステマティックに検知・防止する仕組みを実装できてる?
2022/09/01(木) 17:08:27.97ID:V2mDAtzH
データ競合はあまり遭遇したことないな
無駄に並列化したがるバカがチームにいると地獄を見るだろうというのはわかる
channel絡みのミスで固まるのはよくある
2022/09/01(木) 18:05:50.03ID:Wlby5VAy
>>522
けっこう終了時の後処理とか難しくない?
適当なツールとかだと雑に済ましちゃうし、割ときちんとやろうとすると書けない人多い印象。
2022/09/01(木) 18:16:08.12ID:0As8hqIp
きつい現場のGoは他の言語より殊更きつそうだというのはわかるわ
2022/09/02(金) 02:30:51.60ID:bNDG9t//
channelは複雑なデータのやり取りに使うには難しすぎると感じるね
どこで詰まるかわかったもんじゃないし
公式がまともなフレームワーク用意するわけでもないし
2022/09/02(金) 03:08:08.96ID:xpSIPhaW
epollを使うよりかはマシだし
2022/09/02(金) 08:58:55.58ID:0WCZpZUS
いや、Goに限らない問題でGoのダメなところとか言われてもなぁ
2022/09/02(金) 09:55:02.48ID:zLWkNNSX
いや、けっこうGoに限った問題
channelのユースケースの大部分は現実にはpromise/futureで十分で、遥かにミスを引き起こしにくい
2022/09/02(金) 09:58:48.22ID:0WCZpZUS
例えばCとかでファイルを排他オープンしたままクローズし忘れて書き込みのままになってて、別の箇所で読み込もうとしたけど開けなかったとして
これはC言語の不備だとか言うのか?と
2022/09/02(金) 10:04:00.39ID:0WCZpZUS
>>531
chan のユースケースといったら、パイプとしてストリーム的にデータを流すのが主だと思うんだが、promise, future でどうやって代替するの?
2022/09/02(金) 10:06:18.95ID:0WCZpZUS
>>531
select文のあたりでも書かれてたと思うけど、同期を取る目的じゃなくてパイプからの機能だよチャネル
2022/09/02(金) 10:10:39.85ID:0WCZpZUS
>>531
同期取るなら、sync.WaitGroup 使えばよくない?
2022/09/02(金) 12:33:43.05ID:Xv0heE2X
>>532
そういうことにならないようにGoのdeferやC#のusingやPythonのwithみたいな仕組みを言語機能として提供してるよね?

それらが不要だとでも?
2022/09/02(金) 12:45:23.85ID:bNDG9t//
いや普通に同期を取る使い方もできるだろw
完了通知を待つ使い方
俺もその使い方しかしてない
async/awaitなんで構文として追加しても良いと思うのだけどね
channelは非同期機構を実装するパーツとしては優秀だから
フレームワークが欲しい
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況