Go language part 5
>>992 (前スレ) 読んだ。で、やっぱり奇妙なんだけど、多分オーバーヘッドはないと思うよ。 一般的にはガードページなんて必要なくて、コピーオンライトと同じで、 ページ境界を跨いだ場合はハードウェアで検出出来るから、まず普通はそれを使う。 この場合は自前でのチェックは必要ない(ソフトウェアには必要ない)ので、オーバーヘッドはない。 だからGoの当初の初期スタックサイズが4kだったのは非常に納得出来た。ここまではいい。 これを小さくするならハードウェアのサポート無しになるから当然自前でチェックするしかないが、この場合、 ・2kも大きすぎ。自分でやるならRustのように64Bytesからとか、4kに拘らず凄く小さいスタックサイズから可能だし、普通はそうする。 ・そもそも必要スタックサイズを予見出来ない。というか出来るならコンパイル時に確定的に割り当てれば済んでる。 であって、Rustの実装は非常に納得出来るのだけど、Goのは若干意味不明なんだよ。 (ただまあ何かしら理由はあると思うけど) 2kとかいう、4kに拘ったサイズになってるんだから、多分何かしらハードウェアのサポートを受けてて、 自前ではスタックサイズのチェックはしてないと思うよ。(つまりオーバーヘッドがない) 可能性があるのは、2kをはみ出る時には4k境界を跨ぐようにして(つまりまずは上側を割り当てる) はみ出た時に2kずらしていくとかだけど。 ただこの方式の場合、初期アロケーションだけは4kでされてしまうので、957のベンチでは40MB越えないとおかしくて、矛盾してる。 だから正直よく分からないが、 多分オーバーヘッドのない方式で実装してて、だから2kとかいう中途半端な巨大サイズになってるのではないかと思う。 >>998 (前スレ) 分かりやすい説明ありがとう。発想は面白いね。 確かにその方式だと死蔵メモリは最小限に留められ、Goの問題は解決されてるはずだね。 >>986 (前スレ) 998の通りだと、外部からのプリエンプションではなく、 コルーチンが処理を(自発的に)返してくるから、その単位での切換だろう。 まあこれでも現実的には問題ない気はする。 ちなみに前スレ1000と同じく、1桁少ない1000スレッドで同じPCでgoを測ると $ go version go version go1.13.8 linux/amd64 $ go build main.go && ./t ./main real 12.02s user 0.91s sys 0.22s rss 3808k $ やはり4Mを超えない(rssでいいの?とは思うけど) 推奨NGWord 正規表現で「.{50}」を設定 長文を排除できます >>992 (前スレ) 訂正。他も色々漁って、やっぱりオーバーヘッドはあると思えてきた。 ただし多分0〜4cycle/関数呼び出し程度だね。 主に読んだのは以下とか。 https://github.com/tinygo-org/tinygo/issues/2000 https://dave.cheney.net/2014/06/07/five-things-that-make-go-fast https://dave.cheney.net/2013/06/02/why-is-a-goroutines-stack-infinite ・当初は8kだったが、もっとでかくしろという要求が多かった ・1kに出来てる実装もあるが、こける事もあるから2kがデフォになってる ・同じ図が説明に使われてて、どうやら最初からこの方針らしい 本人達が「チェックしてる」って言うんだからやっぱりそうなんだろう。 一番ありそうな実装は、呼ばれた関数側で最初にチェックする方法で、 つまりローカル変数をスタックに確保するためにスタックポインタからサイズを引く時にチェックする。 これだと、 mov, (sub,) xor, and, jne の追加4命令で(subはチェック無しでも必要) 主にINTパイプで最悪で4cycle、大体の場合はこのあとのLSパイプ(スタック上へのレジスタ待避)に隠れて見えなくなるのではないかと。 だから関数呼び出し毎に0〜4cycのペナルティになる。 ただし、速くなる事はないし、隠れると言っても演算リソースは消費するので、 ハイパースレッディングの場合に相手側のCPUの速度が落ちるのは否めないが。 2k以下にもやれば出来るのだろうけど、やる気がないだけだね。 だから2kで問題なら、コンパイラをいじれば何とかなるのだろうけど、 そこまでやるくらいならRustの方が断然いいね。(後発だから当たり前だけど) 関数呼び出しのオーバーヘッドだけど、高階関数らしい高階関数も無いしそういうややこしいことはジェネレーター使う文化だと思ってるな。Genericsが本流になってきたらどうする気だろうもも思ってる。 なお、比較する関数程度の関数はインライン化される。 https://github.com/golang/go/wiki/CompilerOptimizations >>9 > 高階関数らしい高階関数も無いし いや高階関数は普通に出来る。 https://go-tour-jp.appspot.com/moretypes/25 標準やフレームワークにそれを活用する文化がない、という主張なら俺はその辺は知らん。 >>6 自己レスです。 Goは1.4からamd64だとスタック2k https://github.com/golang/go/issues/7514 今回試した1.13.8だと当該コードがCからgoに変わったりして跡形もなかったが、_StackMin = 2048はそのままだった https://github.com/golang/go/blob/go1.13.8/src/runtime/stack.go つまり2Mであれば残り1.8Mということで矛盾はない >>12 1000個立ち上げなんて1桁減らして測定してるからメモリ使用量がわかりにくいような 素直に1万個と10万個で調べて差を見れば1個あたりがはっきりするような >>13 時間かかるのが嫌で減らしただけです。。。 ちなみに後ろにウェイト入れて、cat /proc/[pid]/statusした結果 VmHWM: 3296 kB VmRSS: 3296 kB VmSwap: 0 kB なので、rssだけでいいと思います。 >>11 > 結局のところ素直にforループを書くのがGoには適していて、 > 汎用の型に適用可能な高階関数を実装しようとするのはミスマッチ これってforEachを実装しようとするのが間違いって事? 或いはmapに高階関数を食わせるのを嫌ってるのか? いずれにしても、やりたきゃやれよ、だと思うが。 オレオレコーディングルール集だが、全般的に現状肯定的なので、 目指すコーディングではなく、今のGoコンパイラ/ランタイム向けのTips集になってる。 これがどれくらい賛同されるのか不明だけど、革新/改革派からは気に入らない内容だろうよ。 Python出身のようだから、この辺C系の「何でもやっていいけど、結果責任は取れ」文化とは根本的に違うのだろう。 一種類のコードになる事を良しとしてる。 > goroutiineのスケジューラはもちろん依頼処理コストが大きい場合をフォーカスしてチューニングされています。 > ひとつのgoroutineがCPUを占有しすぎないように分散してくれる仕組みがありますが、 > 小さすぎる処理コストをまとめるのは実装者の責任で行わなくてはなりません。 > 小さすぎる処理を頻繁に繰り返すだけであればシングルスレッドの方が速い結果が出るのは当たり前なのです。 これとか、1,000,000goroutine全否定だよね。俺は Go信者:1,000,000goroutineでも軽いし速い←嘘つくな GoUser:遅いけど1,000,000goroutineで書きたいんだよ←うむ、遅いと認めるならよろしい。しかし速くなる努力はしたまえ > Goはデバッガビリティのために末尾再帰最適化をあえて実装していません。 いや怠慢でしかないだろ。再帰がデバッグしづらいとか聞いた事無いわ。 ちな、 > 自作ライブラリの利用方法をメソッドチェインで作ろうとする 考えた事無かったけど、try-catchのメリットってメソッドチェインできることか。 なるほどだからろくにメソッドチェイン出来ないPHPだと何ら意義を感じ取れなかったわけだ、納得。 >>15 Goと同じくtry-catchの無いRustはメソッドチェーンが基本の言語だぜ 関数の返り値が基本的にenumとなってエラーも正常値もメソッドチェーンで処理できるようになってる >>14 もしかして俺が前スレ962で単純に40MB足してたのが気になってたのなら申し訳ない。 あれは足しすぎだった。RSSの意味は以下。 https://stackoverflow.com/questions/7880784/what-is-rss-and-vsz-in-linux-memory-management 十分なメモリがある状況で普通に実行させた直後(スワップされてない状況)なら、RSSで問題ない。(はず) 以下は前スレ992内にある図だが https://commons.wikimedia.org/wiki/File:Table_of_x86_Registers_svg.svg これ全部を待避するのに1kB程度かかるらしく(真面目に数えれば正確な数値は出せるが、やる気無し) この分をOS側が待避するので、単純に言えばスレッド数*1kB程OS側のメモリを食ってる。 これがgoroutineだと必要ない(Goランタイム管轄で待避で、RSSに計上されてる)ので文句付けられてる。 だから公平に見るなら、goroutineはRSSそのままで良く、OSのthreadを使うならスレッド数*1KB程度追加かと。 (40MBはスレッド数*4kBにしてるので、多すぎ。 アクセスのない、単なる待避領域なので、ページ単位である必要はない。) そして関数呼び出しのオーバーヘッドについてはそこにモロに書いてあるな。(GitHub上ソースの17行目〜60行目) 0〜4Cycleのオーバーヘッドになる。 方式としては、スタックの底に96Bytes(=40+56)の領域があらかじめ確保してあって、 これらはメモリが足りない時に呼ばれるdeferproc()とmorestack()に必要なスタックサイズなのだが、 逆に言えば96Bytes以下のスタックしか使わない関数ならスタックポインタがそこを越えてなければ問題ないわけで、 以下チェックを通してる。(guardがスタック満タン-96Bytesのアドレスを示してる) > CMPQ guard, SP > JHI 3(PC) > MOVQ m->morearg, $(argsize << 32) > CALL morestack(SB) まあスタック増加がなければINT/BR/NOP/NOPなので、オーバーヘッドは通常1か2Cycleじゃないかと思うけども。 >>12 ちなみにコードが素晴らしくメンテされてれば、 _StackMin = 1024 にするだけで、スタックサイズが1kBになるような気もします。 >>15 そもそも革新、改革がしたいならGoじゃない言語でやれば良いんよ。ひたすらに後方互換を維持してんだし。 1種類のコードになることを良しとしてるのは当初からよ。そうでなければ、gofmtが一切のオプションを持たないはずがない。 多数のgoroutine全否定ではなかろうに。 遅いように書いたgoroutineは遅いとしか言ってない。 ちなみに末尾再起はgdbなんかでデバッグしてるとデバッガビリティ低いと思うよ。俺もそう思う。 普通はデバッグビルドだと末尾再起無効では?cppなんかでも。 >>19 いやあれは「べからず集」なのだから否定だと思うぞ。 まあいいが。 > 普通はデバッグビルドだと末尾再起無効では?cppなんかでも。 そもそもデバッグビルドなら『全ての』最適化は無効だ。そしてその状態で全てのデバッグを行う。 それでリリースビルドでは一発で動く、というかデバッグしないのが基本だ。 (同じ出力を生成する事だけを確認する) 「デバッグビルドでは動くのですが、リリースビルドでは動きません。これってコンパイラのバグですよね?」は初心者あるあるだが、死ねでいい。 リリースビルドでデバッグすると、ブレークポイントも当たらなかったりで、ろくな事はない。 深い再帰とかが例えば演算系なら、毎回再帰前にprintfで全部の値をログに出し、 リリースビルドで動かした出力とdiffを取り、完全一致になってなければバグとして、あくまでデバッグビルドでデバッグする。 そのファイルが数GBになって、普通のdiffでは無理になったら、完全一致専用のdiffを手作りする。 実は浮動小数点だと完全一致はしないが、それなら誤差範囲を指定したスクリプトを書いて比較だ。 というのが俺流で、つまり別の戦術で回避済みだから、 リリースビルドでどんな最適化がされてても、コンパイラがバグってない限り関係ないね。 そしてコンパイラなんてバグってない。俺は誰でも書いてるようなコードしか書かないし。 それ、リリースビルドでデバッグしてる事が問題なのでは? (まあ気持ちは分かるけども。俺も最初はそうしてて、駄目だったので上記になってる) >>16 以下9章だけは読んだ。 https://doc.rust-jp.rs/book-ja/ch09-00-error-handling.html 俺はこれで全く問題ないけども、try-catch派は多分文句を言うような気はする。 あと、これは型をResultで統一すればどの言語でも出来るので、言語と言うよりはフレームワークの設計なのだろう。 (フレームワークを跨いでも統一してる方がいいから、言語としてこれだ!というのは意味はあるが) ただ、エラー処理って方式が統一されてる事が重要だから、今更ではある。 そんな事よりGoはRustのasyncをパクるべきだろう。 コルーチンみたいな名前で実はスレッドではないか!という批判が無くなる。 実は当初goroutineと名付けた時に欲しかったのは、これだったんじゃね?とも思う。 yieldさえあればあっさり出来るのだろうけど。(無くても無理矢理やれば出来るが) つか、無い理由は何なんですかねこれ? template feature実装したgolangのstable公開3月だっけか 作者がc++嫌いだからのgoなのに偉大なるc++への一歩を踏み出そうとしてるのは皮肉な事だが ライブラリ等もかなり便利になるのではないかとかなり楽しみ(´・ω・`) >>17 >18 むしろ前スレ957のベンチ(元記事)では、 "In particular, 10k threads with default stack sizes need about 40mb of page tables to map virtual memory." と訂正しているのだから、前スレ962の計算で40MB足してるのはおかしくない。 ただ、>>4 で再び「957のベンチでは40MB越えないとおかしくて、矛盾してる」と言ってるのが、普通に考えるとRSS対象なので、スレッド数を10kから1kにした俺版でも前スレ1000のC++版との対比する意味もあり、改めてgo版の結果を同じ条件で出した(>>6 )だけ。 結論は同様にRSSは4MBを超えないので、仮想メモリ側にあるという元記事の主張で正しいようにも見える。 しかし、go処理系が不明な元記事と違い、自分でやっていれば実際バージョンは分かるわけで、そこが分かればスタックサイズはソースを見れば一目瞭然ということで経緯と一緒に調べたのが、>>12 で結論としては2Kだったということ。 すると元記事の推測と自分の計測結果には矛盾があり、2KBが仮想メモリにあるかどうかを明確にする必要が出たため、>>14 で/procに頼った。 結論は仮想メモリ(swap)使ってないよって話だったので、少なくとも俺の環境では元記事とは違いRSSでいいという結論が出て、>12の結論とも整合が取れた。 別にdistro標準(ubuntu 20.04)のgo処理系を使っているので、ソースを引っ張ってくれば簡単に1KBに変更は出来るか確認出来ると思うけど、面倒なのでそこまではしない。 >>21 これだけ指摘されて、まだスレッドだと思ってるのは少ないのでは? 一般には coroutine + thread -> goroutine, async/await という認識の人が多数だと思う このasyncおじさんは何も分かってないと思う・・・ nodeでasync/awaitが通るのは、シングルスレッドですべてのメモリーが一緒のためで、Goのようにgoroutineで実際に 割り当てられているCPUやスレッドが分からないようにあえてしている言語で、asyncなんて導入するわけない。 async/awaitがある言語でそれがThreadを混ぜ込める言語もあるが、それだってI/Oをブロックしている処理の終わりに ただ同じスレッドを再割り当てするだけ。スレッド境界を越えてメモリーコピーあるいは同期なんてしてたら破綻する async/awaitのもとになるような、多くのスクリプト言語でyield、つまりジェネレータの重要なユースケースは、I/Oブロックの 待ちで違う処理を行うことだが、それはI/Oバウンドな待ちでしか処理が切り替わらないことを意味する。 async/await,そしてyieldが唯一優れているのは、Goでいうchannelのclose処理が要らないことだけ。 他は全部劣っているし、CPUバウンドでは切り替わらないし、async/awaitなんていうキーワードがプログラミングがしやすいか といえば全然そんなことは無く、async/awaitで書かれたコードと、完全同期の一直線で進むプログラミングでは、互換性に 乏しいライブラリばかりができる。async前提で作られたコードは同期プログラミングでは使えなかったり、同期プログラミングで 作られたライブラリは処理がI/O待ちになっても、asyncが入っていないため非同期では効率が劣る。 決定的には、並列性が大きく劣っている事は言うまでもない。 もちろんこれは速度などという効率の指標ではなく、理論上はCPUコア数=スレッド数で、他はすべて非同期にしたほうが 速いのは、何も考えずとも当たり前。(無駄なコンテキストスイッチや同期処理が発生しないから) 「当初欲しかったのはこれじゃね?」なんていう超ド素人の勝手な想像と思い込み、調べもしない無知でこんなところで ダベっていてもまったく意味ない。 Go言語の作者の一人であるRob Pike氏が「OSスレッドではなく、ユーザー空間スレッド」「メモリ使用量がOSスレッドに 対して、500倍ほど有利」「OSコンテキストスイッチよりも有利」といい、Cの作者として有名な、Kenneth Thompsonが 「C++が嫌いだということで意気投合」「いかなる理由があっても言語にゴミを入れません」と語っているように I/O非同期なんていう半端な偽物は、眼中にない中で、まさしくasync/awaitは1つの利点だけの無用な長物であり プログラミングを複雑にするだけで、つい最近まで総称型さえも、強烈に拒んでいた保守的で長く使えるよう言語仕様を 守り続ける言語に入るわけない。 そんなにやりたかったらお前がforkしてやれ、じゃなきゃGithubでIssueでも投下してこい。それすら出来ないなら お前は不当に他言語を卑下してる卑怯者だぜ。どうせボコボコにされる >>27 流石にその理解はヤバいぞ asyncおじさんをバカにしてる場合じゃない >>27 その主張は間違い 例えば現実にある反例として RustでもGoと同じくワークスティーリングをするM:Nモデルで非同期タスクが動きasync/awaitが導入されている >>28 あまりにも偏った思い込みと勘違いが激しすぎる Rustでもできる、は聞き飽きたんだが、Rust話がしたいのか? Rustの話はRustスレで聞きたいんだが、とうしてRustスレではN:Mグリーンスレッドの優位性の話してないの? 実際Rustでtokioをランタイムとして使ってみたけど、思ったより書き味が良くないしな。 Goのサクッと書いてサクッと、しかも依存の無い、クロスビルドと比べたら相当面倒。 しかもcopreemptiveじゃん。 色々な意味でGoの相手ではない。 >>31 どちらもメリット・デメリットあるからそれは言いすぎでしょ しかも肝心な速度でGoが負けているのだから用途ごとに使い分ければよい話 >>32 その通り、メリデメある、使い分ければ良い→その時点で「相手ではない」と言ってる。 ずっと言ってるけど、1番2番論争は無意味なんよ。 速度ばかりが大切な訳でも無いんだし。 >>23 いや、元記事もそこはちょっと間違ってる。 とはいえ本質は「RSSで全部計上されてるか?」なので大筋は問題ないが。 RSSは「ユーザープロセス空間で、メモリ上に配置されてる物」なので、元記事の通り、スワップされてれば計上されないが、 そもそもこの計測方法では普通はスワップされない。 ただ、考慮してるのは"Thread bookkeeping"であって、 kernel(OS)がこれに使うメモリがRSSに計上されてないから問題だ、というのはあってる。 だから俺はそれを足してる。 Goでは、実はこの部分も売りにしてて、以下は8の2つ目だが > https://dave.cheney.net/2014/06/07/five-things-that-make-go-fast > The switch between goroutines only happens at well defined points, when an explicit call is made to the Go runtime scheduler. > The compiler knows the registers which are in use and saves them automatically. むやみにプリエンプトせず、スイッチングポイントを考えて、必要ないレジスタは待避してない。 考えられるのは ・そもそもセグメントレジスタなんて普通は使わないから待避する必要がない。(レガシー) ・関数の途中でプリエンプトせず、関数呼び出し単位でスイッチなら、 呼び出し規約上の破壊レジスタ(a,b,c,d)は待避する必要がない。 ・そのgoroutineの処理にSSE命令が存在しなければ、SSE系レジスタを待避する必要がない。FPU(x87)も同様。 とかになる。 (なおこれを突き詰めたらRustの「コルーチンのyieldでスイッチすれば、スタックも要らん」になる) そして現実的に多くの場合SSE系命令は不要で、必要待避領域は多分半分以下にはなるので、(面倒だから数えてないが) Goは半分以下にする努力してるのにRSSだと計上され、OS任せだと丸々必要なのにRSSには計上されないので、 当然の如く突っ込まれる事になる。 (その他細かいフラグ類は沢山あるだろうけど、多くはbit単位であり容量としてはゴミなので無視) だから最小フットプリントなら1/3程度で、 あまり余計なことしなければスイッチングコストも1/3程度としていいのではないかと。 逆に言えば、threadよりも3倍程度のgoroutineで済むのなら、速くてコードも綺麗だが、 それ以上なら遅くなるという事。 >>27 ,28 どこから突っ込めば状態なので、最初の部分だけ。 > nodeでasync/awaitが通るのは、シングルスレッドですべてのメモリーが一緒のためで、 これは多分プロセスとスレッドの区別が出来てない。 プロセスは別空間だがスレッドは同一空間で、逆に言えばその程度の違いしかないが。 > e.g. Linux doesn’t distinguish between threads and processes and both are called tasks. > https://codeburst.io/why-goroutines-are-not-lightweight-threads-7c460c1f155f#396b > Goのようにgoroutineで実際に割り当てられているCPUやスレッドが分からないようにあえてしている言語で 一般的に非同期の場合はどのCPUにどの順番で処理されても動くように組む必要があり、 実際にC#でもそう。 JSもそう。(ただしJSのプログラミングモデルからは見えない) この発言は上記の勘違い、(とは言っても普通の勘違いとは逆で) Goはgoroutineがそれぞれ「別空間」で動いていると勘違いしてるからだと思うのだが、それはない。 重ならないようにコンパイラが割り当ててくれてるだけで、同一空間だ。 >>35 元記事はGoのバージョンが確認できず、goroutine当たりのスタックサイズは不明なため、断定してないだけで、時期を考えると2KBだから恐らくRSSだろうとは思っている(明確に言えるのは自分で計測した方だけ)。 カーネルで管理されているメモリは4KB/2KBとかじゃないと思うし、数字としてはどこにも表れないので、それは差があるとだけしておけばいい。 元記事の筆者が加算しているのはgoroutineスタック分以外は全てRSSに入る前提の元、未計測の仮想メモリには最大40MB入ることがあるはずという計算。 > Goでは、実はこの部分も売りにしてて、以下は8の2つ目だが...コルーチンのyieldでスイッチ... Goの「スイッチングポイント」は現状誰も明示しておらず、保存しているものも、どこなのかも、推測の範疇を出ておらず、議論は無意味。 >>33 Rustはどう見てもGoの相手でしょう 2019年に非同期本対応のRustが誕生するまでは明らかにGoの独壇場だった 今はRustがGoと同様にN:M非同期タスクを実現してGoのようにチャネルを使って全く同じ動作が可能となった上でasync/awaitも対応 そしてRustのほうが速いのだから比較対象として話が出るのは仕方ない >>37 > goroutineスタック分以外は全てRSSに入る前提の元 いやgoroutineスタック分はユーザー空間だからスワップアウトされてない限りRSSには計上される。 そしてスワップアウトは「必要ない限りやらない」のが基本だから普通にベンチマークしてれば問題ない。 (同時にメモリイーターなプロセスを走らせておかないと速攻スワップアウトなんてされない) > カーネルで管理されているメモリは4KB/2KBとかじゃないと思うし 『プロセス』を管理するために必要なカーネル側のメモリは4kBとかではない。 PTE(PageTableEntry=MMUの中身データ)だけでもメモリ128MBなら4k/pageだと128kB(=32kentry*4Bytes)必要になる。 (ただしラージページ《2M/page》なら256Bytesで済むが) だから『プロセス』は軽くない。 一方、『スレッド』についてはこの部分は必要なく、追加のスレッドによって増えるカーネル側メモリは、 スレッド管理分のフラグ類の数Bytesと、待避領域の1kBだけで済むはず。 4k/threadの見積もりは多すぎ。(多分) > Goの「スイッチングポイント」は現状誰も明示しておらず、保存しているものも、どこなのかも、推測の範疇を出ておらず、議論は無意味。 それはそうだが、多分合ってると思うよ。ただ、 > どこなのかも、 これについては間違いなくユーザー空間のはずだよ。カーネル側に保存する意味がないし、余計に遅くなる。 誤解無いようにくどいが言っておくと、 OSの管轄でマシンスレッドからプリエンプトする場合、各マシンスレッドの状態待避はカーネルがカーネル空間側に行う。 Goランタイムの管轄でgoroutineを切り替える場合、各goroutineの状態待避はGoランタイムがユーザー空間側に行う。 (まさかGoランタイムってカーネルモードで動いてたりする?それなら話は違ってくるが) >>38 明らかにユースケースが違うし、コンビニに行くのにF1乗るみたいな話だぞそれ。 スクーター以上のそれなりに早い二輪車が欲しいんだよ。 >>39 違うのでは? ユーザスレッドでもカーネルスレッドでも動いてる。 普段はgoroutineはユーザ空間で動いてるが、その上でカーネルスレッド毎に偏りがあったらスティールするでしょ。 >>41 君は27? > 普段はgoroutineはユーザ空間で動いてるが、その上でカーネルスレッド毎に偏りがあったらスティールするでしょ。 これは明らかに分かってない奴の言い分だが。 >>39 > > goroutineスタック分以外は全てRSSに入る前提の元 > いやgoroutineスタック分はユーザー空間だからスワップアウトされてない限りRSSには計上される。 だから元記事の筆者がそう考えているという話で、これは俺の環境とは違うからRSSなのか仮想メモリなのか断定できないと言ってるだけ。 よく読んで欲しい。 > > どこなのかも、 > これについては間違いなくユーザー空間のはずだよ。カーネル側に保存する意味がないし、余計に遅くなる。 アドレス空間の話ではなく、スイッチングポイントは典型的にはyield直前とかのはずなんだけど、そこ実際にどこだか誰も調べてないよね?と言ってる。 多分とか入るのに他所様のお庭と比較するのはおこがましい。 >>43 > だから元記事の筆者がそう考えているという話で それはそうだが、俺らはそのデータを見てる立場なので、それが正しいかをチェックする事になるだろ。 これも誤解無いように言っておくと、 元記事の作者は、(彼的には)正しいと思ってるからそう書いている。俺から見てもRSSで問題なく、正しくデータは取れてると思う。 (ただし考察の一部に微妙に間違いが含まれているので、その部分を指摘してるが、大局に影響はない) ちなみに君のデータも、正しく取れてて、問題ないように見える。 RSSでいいのか心配のようなので、こちらからも「RSSで問題ない」との意見を付けた。 > アドレス空間の話ではなく 上記RSSの話に引っ張られてしまって勘違いした。すまん。 これ以上進めるには精度が足りないというのは了解した。 俺的にはこの程度の精度でも前進して構わないというノリなのだが、 もっと厳密に正確に確認していきたい人だとストレスが溜まるとは思う。 掘り下げたい人がいれば、12みたいにソースの該当箇所を提示してくれれば、確認の手伝いくらいはする。 >>44 了解。すまんがこれ以上は俺はやらない。main.goのスレッド数に対するRSSのグラフ(svg)だけ貼っとく。 https://jsfiddle.net/9b0kujsL/ そのうち消えると思うけど、ここには貼れないサイズだったので仕方ない。 >>38 Rustのビルド速度は凄まじく遅いだろ。競合にならん。 Rust信者はgoスレに書き込む前に"Build fast, reliable, and efficient software at scale"を100万回唱えろ。 >>46 うっかりスレッドって書いちゃったけどgoroutineの間違いです(グラフも) >>46 了解。では感想だけ。 今時はグラフはsvgで作るのかーとちょっと驚いた。ググったら結構あるみたいだけどさ。まあそれはさておき、 > f(x) = 2.6396 x + 1186.8 完全にリニアで、2kBはスタックとして、残り0.6はちと多い。G構造体は以下(前スレ805内のリンク内) https://github.com/golang/go/blob/master/src/runtime/runtime2.go#L403-L498 にあるが、51個もメンバがある巨大構造体で、こんなに必要なのか?とは思う。 まあ「税金」として0.6kBかかるのなら、無理にスタックを1kBにケチる意味はないから、デフォ2kBは妥当な判断に見える。 これについてはlinuxと比較しないと妥当性は検討出来ないが、 妥当性を検討するためにはLinuxを見る必要がある。これは同様に(前スレ805内の記事11章)以下にある。 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/sched.h#n657 見た目goよりでかいし、ifdefが多すぎて数える気にすらならない。 とはいえlinuxのはプロセスと共用だし、そもそも大量に起動する用途向けではないので多少大きくても問題ない。 おそらくあれこれ機能を足していくうちに肥大化したのだろうとは思う。 ただこれに対抗するならgoのはでかすぎ。 10倍起動するつもりなら、サイズは1/10に抑えないと並べない。(今は多分数分の一程度) JSはここら辺はただのFIFOで、1ジョブ当たりポインタ数個分で実装出来る程度の機能しかない。だから速い。 Goのも既に肥大化しすぎてる。 ちょっと考えてみ?600Bytes=ポインタ*75個分で、一体何の制御をしたらそんなに必要なのかと。 51個のメンバがある=起動/停止時にその51個のメンバをチェック/更新するコードを通す事になる =起動/停止時に「税金」的に数百サイクルは必要、となる。 ここら辺はやっぱりチューニングが狂ってる。 『軽量』OSじゃないといけないんだけど、 オレオレOS作りたい奴がランタイム作ってて機能が肥大化してるのではないかと。 スケジューラが売りのようだが、ベアメタルではなくOS上で動かすのだから、無くてもOS側がそれなりにはやってくれる。 それをスケジューラ作りたいだけの奴が作っただけのように見える。 アプリを速くしたいのではなく、スケジューラを作り込みたいだけだから、チューニングが狂う。 この辺、JSはエンジン内の仕組みなんて誰も評価しないでしょ。 速いか遅いかだけ。だからチューニングが狂わない。 OSがそれなりにさばかないよ。グリーンスレッドの価値を全否定だな。 JSのエンジン、定期的に話題になるだろ。 V8もTurbofan+Ignitionに変わってすぐはソース読んでたぞ。 https://jsfiddle.net/z1bvwt3L/1/ 1:1スレッドでのC++/Rustの結果も併記した(Rustのバージョンは1.58.1) 標準機能で記述する縛りでロジックだけ同じにすると現状ではこうだということ M:NをC++/Rustで自前準備すれば別の比較ができるかもね >>55 全く意味のない比較になっている Goではm:nグリーンスレッド利用 C++とRusyでは1:1つまりOSスレッド利用 ちゃんと3者ともにm:nグリーンスレッド利用で比較しなさい >>57 「標準機能で記述する縛りでロジックだけ同じ」という条件だとそれは無理な相談 むしろm:nでないとならない条件では成立しない > ちゃんと3者ともにm:nグリーンスレッド利用で比較しなさい 上記条件にはならないが、どうしてもやりたければお前がやれ C++は20を使えば標準機能だけで実装できるはず Rustが標準機能だけで実装可能かは知らない Rustの標準ライブラリはunsafeのオンパレードだなw ライブラリもOS機能を使うならunsafeも致し方ないのではないだろうか、と誤爆にレス >>58 わざわざGoスレでくだ巻いてる方がやれよ。 できなけりゃGoを使うよ。 >>63 俺はGoのパフォーマンス測定をGoスレで尋ねてその後も調査してるだけだけ(すでに終了は宣言した) ただまだ妥当性がどうのと言ってる人がいるから、とりあえず恐らく同じくデフォルトが通常2KなOSスレッドスタックを使ったRustとC++の結果を貼っただけ 結果は1:1でthreadが動いてるRust/C++の完敗だが、ロジック同程度で標準機能だけという条件なら仕方ないねって話をしただけだぞ まだ文句があるなら自分でやれと言って何が悪い お前がGoを使おうと何を使おうと俺はどうでもいい >>64 m:nとなるgoroutineを用いたGoと 1:1となるOSスレッドだけを用いたC++&Rustを比較することは無意味 比較したいならばC++&Rust側でもm:nでやりなさい >>64 勝ち負けを認めさせたいから言ったのでは無く、それ以上はRustスレでやれと言ってる。 C++スレでもRustスレでもここでも同じで無意味 m:nとなるgoroutineを用いたGoと 1:1となるOSスレッドだけを用いたC++&Rustを比較することはナンセンス thread単品で制御できないgoじゃこういう計測ができないのも理解できないとは・・・ 何しにgoスレに来てるのやら C++とRustでもOSスレッドではなくm:nグリーンスレッドを使えばよいだけだろ >>64 妥当性がどうのこうのは「GoランタイムのG実装」であって、君のデータについてではない。 君のデータは妥当だし正確だと思うよ。 >>54 > OSがそれなりにさばかないよ。 GOMAXPROCSがCore数と同じ事に拘ってるからだよ。だから完全な(=高価な)スケジューリングが必要になる。 Core数よりも多いMにして、優先順位を低く設定しておけば、CPUが空いてればそのMで実行される。(これはOSがやってくれる) これなら今のランタイムがやってるようなスケジューリング管理なんて丸々必要なくなる。 C#がこれで、空きCPUがあれば新規スレッドをプールに追加して、実行させるだけでしょ。 (ただしGoの場合は同期チャネルなので一々止まりまくり、この場合は確かにそのままOSに任せても駄目で、 Rustみたいに同期受信待ちをコルーチン化して送信時に受信側goroutineのコードを直接実行する実装の方が向いてるが、 《だからthreadなのにコルーチンと名付けたのか?》 ここら辺はジョブの重さと同期チャネル量の兼ね合いで、第一選択肢として力業(スケジューラ)で解決、という判断は妥当ではあるが) > グリーンスレッドの価値を全否定だな。 「コンテキストスイッチのオーバーヘッドを減らす」Goより、 「コンテキストスイッチ自体を無くす」非同期の方が原理的に速い。 ただし非同期はソースがうざかったが、async文法でまあ何とかなった。 よって肯定する部分がない。当然他言語も全く追従しない。(今後出てくるかもだが) 逆に非同期はJS/C#/Rustと来てるだろ。良いと見られている証拠。 > V8もTurbofan+Ignitionに変わってすぐはソース読んでたぞ。 それは君が興味があるからだろ。 大半のJSerはC++は読めないし、読む気もない。ブラウザが速ければそれで良しだよ。 わざわざ自前でスレッド管理するのなら、OSと被ってないところをやらないと。 スケジューリングはOSがやってくれるのだから任せておけばいいし、自前でやっても余計に遅くなるだけ。 残ってるとすればスレッド間通信で、これは確かにOSのは遅い、というより動くようにしか出来てない。(そして非同期) だからそこそこ速い同期チャネルが絶対不可欠なアプリがあれば、と思って考えてみたが、やっぱり俺は思いつかないね。 チャンネルが同期なのはバッファが無いとき お前は本当に人な話を聞かないし何も読まないな。 >>71 > 妥当性がどうのこうのは「GoランタイムのG実装」であって、君のデータについてではない。 うん、それは分かってたんだけど、定量的なデータがないとその妥当性分からんでしょ M:Nのgoroutineだからと言って調子に乗って1:1の10倍積むと、俺の環境だとrssは超えてしまうってことがデータから分かる データは簡単に取れる状況だったから、取っただけ Windowsでアップデート後にVScodeでテストを走らせると1.14.13でコンパイルされてるためツールバージョン1.17.7とマッチしませんと言われる setting.jsonでgo.gopathを環境変数のGOPATHに合わせてビルドしてもダメ かといってアップデートされたディレクトリを指定してもダメ 環境変数のGOPATHのgo.exeがアップデートでは更新されていないためなのか でもツール類はアップデートされてたりしてもう訳がわからない どう処置したらいいの? ちなみに、システム環境変数のPathには$GOPATH\binのパスが入れてある いや…落ち着いてエラーログを見たら、例えばruntime/internal/sysが、とか言ってる 参照モジュール? で、go.sum を消して再ビルドしたけど同じ結果 とりあえず全部をアップデート先に統合する方向で納めた バージョン混在状態だとどうしたらベストなのだろう? 環境的には最新に統合してgo.modでのバージョン記述に頼ればいい? >>74 つまりリソース的にGoroutineはOSのスレッドの数倍しか立ち上げられないということ? >>74 それはご丁寧にどうも。ついでなら、 > C++は20を使えば標準機能だけで実装できるはず (>>58 ) これについてもキーワードかURLだけでも教えてくれれば助かる。見に行く。 greenthreadが採用されたって事か? (C++の場合は『全部入り』を目指してるからいつかは入るとは思うが) >>73 あの文法は同期が主目的で非同期も問題なく書けるだけ。 OSのスレッド間通信は非同期しかなく、 同期したければ自前でループかサスペンド/ウェイクアップするしかない。 だからそんなに同期を取る事はなく、仕方なくやる程度。 そしてそれで何とかなってる=従来分野は非同期で問題なく書けてる。 同期の場合、シェークハンド等の単純な方法なら同期プリミティブ無しで書ける。 多分もっと複雑な事も出来るのだろう。だけど俺にはそれに適した分野が分からない。 (従来分野は問題ないので、従来既に困ってたか新分野かだが、思いつかない) ランタイムの仕様が無駄に大きいと、実行速度がそのまま低下する。 JSが無駄に速いのは、仕様が小さい(最小限に絞ってる)のもある。 チャネルの実装は以下(前スレ805内リンク8章)にあるが、 https://zenn.dev/hsaki/books/golang-concurrency/viewer/chaninternal こんなまどろっこしい実装になってる理由は、同期(も出来る構造)だからだ。 非同期専用ならもっと単純な実装で済むし、速い。 だから優位性を発揮するためには、「同期チャネル」がないと辛いアプリがあれば分かりやすいが、 俺には今のところ思いつかないって話。 (非同期チャネルだと「空になったら止まる」という間抜けな同期しか出来ないが、実際それで十分という話) Docker CLIのダウンロードみたいな 複数のプログレスバーを出せるライブラリほしい 何がおすすめ? >>64 そこは標準機能だけ対象といってもその定義が難しい そのRustは標準(std)ライブラリーは最小限のものしかなくて 例えば乱数も暗号関係(TLS含む)も正規表現もJSONもHTTPも非同期ランタイムも何もかもstdに含まれていない 全てデファクトスタンダードで賄う方針だからそれらを標準機能として採用して比較してよい? rustはもう少し標準ライブラリにも機能増やして欲しい。 >>88 俺が依頼してる話でもないから俺に聞かれても・・・ではある。そもそもここgoスレだし何のためにそれをしたいのかすら分からない。 単純に話を聞く限り ・goは言語機能で賄っているのに標準ライブラリ以外を使うとか流石に比較にならないと思う ・C++の標準ライブラリにもjsonやhttpや暗号はない ・同じロジックにこだわらず、追加のロジックで不足機能を補うなら、可搬性(プラットフォームごとに実行コードが変わらない)が必要 のではないかと思う 非同期処理ですら紛糾して仕上がったのが2019/11な赤ん坊に無茶言うなって Rustのコンセプトは分かるけど、学習難易度とライブラリの貧困さを何とかしないと浮かばれずにいつの間にか沈むぞ そんなにライブラリ貧困なの? おれもまだ勉強中なんだけど何のライブラリで困るのか具体的に教えてくれ 勉強がてら試しに作ってみるかも >>91 学習難易度はキノコードが動画作れば解決w >>91 Rustも難易度は高くなくて広く色んなプログラミング言語をやってきた者には容易 例えばC言語などのenumを関数型言語の代数的データ型で拡張したのがRustのenum そういうのを理解しているとメソッドによる代数的演算やパターンマッチングなどRustの基本機能も習得がすぐ あるいは例えばGoでも構造体ベースのイテレータパターンを書いたことあればRustのイテレータも楽勝といった具合 GoやCのfor ; ; 文はRustには存在せずイテレータに集約されており更にメソッド連鎖させて操作の分離と抽象化でわかりやすく書くことが多い >>92 むしろRustは民主主義方式なのでライブラリは多種多様に豊富 異なる考え方で作られたものが両立している分野もあるし後から優れたものが出てきてシェア拡大も起きたりしている 代わりに標準ライブラリ(std)は必要最小限のものしかなく その一部であるコア標準ライブラリ(core)はヒープがなくても動作する更なる最小セットを提供 間違ってる上にスレ違いすぎるな 言語比較がしたいなら↓へ 次世代言語23 Go Nim Rust Swift Kotlin TypeScript https://mevius.5ch.net/test/read.cgi/tech/1638086359/ >>96 間違ったことは書いていない 質問や話題があったからそれに対して答えたまで >>95 民主主義方式はc++みたいに標準委員会方式の場合だろ。 実装複数でデファクトスタンダードを競わせるってのは戦国時代方式だよ。 >>99 あの標準委員会方式は強いて言えば一党独裁制だが紛糾ちぐはぐに近い そしてC++の標準拡張が失敗してきた歴史を見ても反面教師としたのは理解できる >>102 荒らしに荒さないでって言ってるようなもんだぞ 話が通じる相手ならとっくにやめてるだろ 相手にせずにNGなどで無視したほうがいい そうだね じゃあ 1.18 の話でもしよう せっかく Generics が入るみたいのに、slice での Map、Reduce、Filter みたいなユーティリティが提供されないっぽいよね? 今はとりあえず準標準といえるものがこれ https://pkg.go.dev/golang.org/x/exp/slices だと思うんだけど、そのうち増えるのかな? 例えばこんな感じの実装↓でいいと思うんだけど、本家でなんか議論されてるん? Go追いかけてるひとおせーて! https://gotipplay.golang.org/p/Y2cpCCPjKqr 他のインタフェースが検討されてるとしたら、メソッドチェーンできるようにしたい、とかかな? GoスレでRustRust言う奴から得るもんは何もない 失せろ >>106 メソッドチェーンの途中で>>105 の実装のように毎回スライスを生成するのは無駄で遅いから 各メソッドをイテレータとして実装して中間生成物を作らないようにすべきかな たしかに効率的にするならイテレータにしないとね それで簡単に仕様が決まらんのかな 今一番rustの話で盛り上がるのがこのスレだからな >>113 Tauriで盛り上がってる electronをRustで実装しなおしたら性能上がりすぎRust覇権とかwww 馬鹿だね〜 >>110 それ7年前のRust 1.0公開時からサポートしてる機能だが Rustはプル型にすることで無駄な動きをゼロにしつつメソッドチェーンの形になってもヒープを使わずスタック上のみで動く特徴がある しかしGoでは受け入れられる方針なのだろうか? 一方でプッシュ型であるチャネルを使った実装だとプッシュ型にすることでのムダよりもgoroutineを使うオーバーヘッドが大きい >>40 そのとおり。 決定的なのは、goをRustで実装してしまえばいいw それがすべてだろw逆にRustをgoで実装することは何万年立っても不可能なんだからw なぜならgcのある言語でgcのない言語を実装できないから Istioがまさにそうだよ > RustをGoで実装 フリーランスだけど未経験OKのところに応募してみた。 採用されたらよろしくな。 >>117 なんでだよw 言語処理系にGCがあるかないかと、それから作られるバイナリにGCがあるかないかなんか関係ないだろwwww インタプリタじゃあるまいし。 >>117 あのーGoもRustも最終的に吐き出すのは機械語のコードだよ? その場合GCはランタイムに含まれるんですがそれは実装する言語関係ないですよ? >>122 goでメモリ管理まで書くの?そしたら所有権とかの概念があるRustに軍配があがるだろ >>123 Rustの所有権とかのメモリ管理はコンパイル時に行われる静的な処理が中心となるので どんな言語でも書けると思う RustあげてるやつがRustの良さを何も理解できてないのがホント阿呆らしい >>124 単に書けるのと言語でサポートされてるのとはちがうんだよなあ 特に多くのは人が関わるプロジェクトでは >>127 Rustのメモリ管理の実現方式を理解出来てないと思う コンパイル時に行われることと、コンパイルされた機械語が行うことの区別は出来てる? Rustの所有権の処理はコンパイル時に行われるので、そのコンパイラがRustで書かれていようとGoで書かれていようと関係無い >>127 「サポート」じゃなくて「強制」。 ほんと、Rust信者はRustのメリット・デメリットを知らんな。 >>123 どの言語に対するコンパイラもインタプリタも別のほとんどの言語で書ける 例えばプリミティブ以外は全てオブジェクト型になってしまうJavaScriptでもGoやRustのコンパイラを記述可能 もちろん記述可能性とは別の話として言語機能の強力さや高速性と省メモリ等の点から現存言語ではRustが最も有利であるだけにすぎない >>123 いやだからコンパイル後に動くのはランタイムのコードなの Goとか関係ないの ランタイムって意味わかる? 機械語に含まれる標準ライブラリやメモリ管理のコードのことだよ >>132 痛いところをつかれた証拠だな よほど都合が悪いらしいwwww >>129 そうそれ だが強制するとしないでは天と地の差がある つまりセキュアが保証されるかされないかということに影響する コンパイラの仕事が何なのか知らない人がRustを推すのは流石に恥ずかしいからやめてくれ Rust使ってる身としてはすごく迷惑 >>134 Rustの言語仕様の所有権による実行コードの安全性の保障は、コンパイラをRustで書いてもGoで書いても、同じように得られる 逆にRustでコンパイラ書いたとしても、それによってコンパイルされたコードがRustの所有権による安全性を得られるわけじゃない やはりおじさんはVM系言語しか使ったことがないようだな 会話が成立しない訳だ GoスレでマヌケなRust推しが暴れているという地獄 Rustの方が言語機能の強力さや高速性と省メモリ等の点から最も有利なだけにすぎないからね ほとんどの言語でGoのコンパイラもRustのコンパイラも作ることが可能 この両者の区別ができないとね いわゆるVM系の言語(Java、C#、JavaScript、Python、Rubyなど)はランタイム自体がインタプリタに含まれてるので意識しないんだろうな なんか普通に恥ずかしいよね コンパイルが何をしているのかも知らなかったなんて 最近のVM系言語でもJITしてるし理解してるものかと思ってた JITはインタプリタのランタイムのスタックとマシンコードのスタックを引き継ぐ処理とか内部でやってる そういうのもわからないんだ rustだなんだという前に大学に編入してCSを勉強した方が良いのではないか なんでここまでボロが出る前にスッとROMに徹せられないんだろうね? Rustのことは忘れて スライスってよく考えたら中にサイズとキャパシティ持ってるだろうからlen(スライス)はそれを見てるだけなのか? struct の中にスライスと長さを持たせてたよ…orz RustのスライスとGoのスライスは概念が異なる Rustのスライスはポインタと長さの2点のみを持ち常に「参照」である つまり「参照」ということは「本体」がある 本体は配列(=そのままだとスタック上で長さ固定)やVec(=ヒープ上で長さ可変)など Rustのスライスはそれら本体の一部(もしくは全体)を指す「参照」という従属物 このように概念を整理して分離したことがGCのないRustの効率の良さに繋がっている >>148 Go のスライスの内部実装も知らない男の人って・・・ Goのスライスはうっかりデータ競合を起こしても自己責任 別変数に代入して各々に対して値を書き換えたりappendしたり可能だがもちろん互いに競合する そして苦肉の策の結果としてappendでキャパシティを超えた時に両者がそこから分岐 一方でRustは言語仕様でデータ競合を起さないことを保証している Goのスライスは実質的には可変長配列として使うからね 嘘つきはRustの始まり。std::syncだって同期とが標準モジュールに入ってるし、atomic型だって同じ。並列操作ではgoは他の 言語に抜き出ている。goが競合を起こすのはgoroutine同士でデータを共有するような、”古い老人のような作り方”をしている からでchannelを通さない、sync.Mutexを使ったこともないasync/awaitだけでRustライブラリの中がArc<Mutex<T>>に なってる事も知らないド素人がイキがってるだけ。 スレ違いなので荒らすのは止めましょう refrect.DeepEqual() って便利 だけど、単体テストでNG出たんで今日は寝ますね (…どこが食い違ってるのか教えてはくれない) Javaやpythonからgoに来た人って絶対Rustにも行くよね?w 皆さんストリンガーって保険のためにとか実装してる? 別にRustを使ってもデータ競合は防げるけど競合状態は防げないし、データ競合を防ぐ目的のために面倒なメモリ管理をやる気にはならないな >>151 Goのスライスは言語設計ミスだけど 言語仕様を複雑にしたくないために起きている不幸の一つ データ競合についてはGoは言語としてサポートせずプログラマーの腕に任せる方針 >>162 中途半端な仕様だな それって意味ないだろ 今からGoですを勉強するのって意味ない? rustとかいうやつのほうがいいの? Goの採用はスタートアップなんかでも結構多いので意味無くはない Rustは実際にはまだほとんど無い とはいえGoをあえて勉強する必要があるかは微妙だな こんなの経験なくてもチームに入ってからなんとなく空気読んで十分使えるし、 それができる程度に他言語の経験がないのであればGoはあまり意味のない言語だ >>164 「勉強」の意味による。 仕事につながる技術を身に着けたいなら、普及率が高くて求人も多いJavaやcのほうがいい。 学問としてプログラム言語を勉強したいなら、より原理的なlisp(scheme),haskell,cのほうがいい。 趣味でプログラムするのに勉強したいなら、手軽で教本も多いpythonあたりかね。 goやRustは中途半端なので、最初の選択肢にはならない。 Goの戦場はニッチだからねぇ 汎用を求めるならJavaやC# ハイエンドならC++ いっちょ大穴狙うならRust (次の次くらいに来るかも) Java, C# は使えて当然、C++が分かるなら誉めてもらえる >>164 勉強はいつだって意味があるよ 2〜3日入門書を読めば大体分かるだろ 入門書の値段分ぐらいは価値があるよ goは言語自体はあまり面白くないからね 仕事で使う予定がないならもっと尖った言語の方が面白いだろう みなさんありがとうございます。 Javaとphpを仕事で使っていますが、Goの何でも自力で書く的なものに惹かれて将来的には仕事で使いたいと思いました。 >>164 goかrustの2択だったらrustかな? goは中途半端になってしまった。 >>166 の言う通りケースバイケースすぎてなんとも もうちょっと素性や目的を明かしてくれないとね あらゆるケースを想定して書くのはめんどう Goは文法だけなら超簡単だけど channelを使った並行プログラミングのパターンをしっかり身につけてないと使い物にはならない >>171 そういう志向ならgo もいいけどcのほうが勉強になると思う。 なんだかんだ言ってもサンプルとか解説はcのほうが多いし。 >>171 > Javaとphpを仕事で使っています (中略) 将来的には仕事で使いたい どう考えてもJS一択。現在Javaメインで鯖周りだけPHPなら、明日から使える。 > 何でも自力で書く的なものに惹かれて 分野ごとに言語が違って一々勉強が必要なのはナンセンスじゃね?とは思うだろうが、 実際はJavaでも何でも出来るが、 例えばJavaでGUIやるよりは勉強の手間含んでも他言語の方がマシなのでみんなそうしてる。 Javaを既に普通に使いこなしているのなら、Goを『学ぶ』意味はない。方言程度で使えるはず。 引っかかるとしたらポインタだが、ポインタを学ぶならCの方がいい。 俺はパラダイム違いという意味でもJSだと思うけどね。関数ポインタ/クロージャを常用する言語をやった方がいい。 https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E%E3%81%AF%E8%A4%87%E6%95%B0%E7%BF%92%E5%BE%97%E3%81%99%E3%81%B9%E3%81%8D/ >>176 も>>177 も勧めてるけどC言語は基礎教養として必須 C言語のあとRustへ進めば進みやすい上に今どきの各種プログラミングパラダイムを押さえられていいかな >>178 JavaやっているやつにRust勧めるなよ。c++でRAIIとunique ptr勉強してからじゃないと無理。 GC前提のgo のほうが近道だわ。 >>180 C++は以前の「筋が悪いが代替がないから使う」から今は「避けることができる」言語 今となっては学ぶべきでない言語として大方のコンセンサスがあります C→Rustと進むのが非常にわかりやすくてベスト ウェブ業界にいるんなら、Rustの案件は将来も少ないだろうし、 >>171 が仕事で使う目的で学ぶっていう意味でいうならGoのほうがええやろ 教養としてならRustのほうが学ぶこと多くて面白いけど >>182 それならばウェブ業界で今急速に進んでいるのがWebAssembly そしてWebAssemblyの記述言語は圧倒的1位がRust >>180 ただGoだと何も「新しくは」できなくね? ガチ鯖はJavaで、ライト鯖はPHPで既に書けるなら、Goが他に活躍してる分野って何? 今時のデスクトップアプリはGUI無しとかあり得ないから、CLIアプリとか?ならJavaで全く問題ない。 Javaが動かせない貧弱環境(=非x86、非linux、つまり大体組み込み)ならC一択だし。 >>181 > C++は (中略) 今となっては学ぶべきでない言語として大方のコンセンサスがあります これはない。お前の周りがトチ狂ってるだけ。Rust界隈はそうなのかもしれんが。 俺はRustは最終的に死ぬと思ってる。 C++とはコミュニティの規模が多分4桁違うし、FireFoxを殺したのはRustだし。 (まあ俺はGoも最終的に死ぬと思ってるんだが) 初心者は「全機能を使いこなす事が必要」だと思ってるみたいだが、これは明確な間違いで、 C++なんて全部入りなんだから全機能なんて使ってる奴は居ない。 (例えばインラインアセンブラも普通に出来るが、常用されても困るわけだし) C++は元々「必要な機能を選んで使う」思想で、 初心者は「何が必要で何が不要か」判断出来ないから適切に使うのはかなり無理。 で、そういう奴は大体C++の悪口を言う事になるわけだが、ほぼ「肥大化してる」だけだろ。 それはお前が適切に取捨選択出来ないだけだ馬鹿タレ、でしかない。 >C++は元々「必要な機能を選んで使う」思想で、 >初心者は「何が必要で何が不要か」判断出来ないから適切に使うのはかなり無理。 一人で使う分には自分が理解したところから使えばいいんだがチーム開発だと悩ましいよな。 書いた本人以外理解が難しいコードなんてのも簡単に量産されるし。 >>184 そこは冷静になって純粋に言語機能をC++とRustで比べてみればいいんじゃないか 言語としてはC++が勝っている点がほぼなくC++の様々な欠点をRustが改善解消 だからこそ大手IT各社が揃って共同でRust foundationを起ち上げるなど垣根を超えて惚れ込んでいる >>185 だから「コーディングルール」で切るんだよ。 つか、多分、C++とそれ例外では「コーディングルール」自体の意味が違う。 C++のは機能も使い方も制限する。Goとかだと見た目だけだろ。 (Goの場合は見た目もディレクトリ構成も画一だからもしかして何もない? googleもC++/JS/PythonはあるがGoのはなさそう) C++に問題があるとすれば、「難しいコードを書くことに何らブレーキがない」事で、 これをコーディングルールで補ってる。 C++以外の言語は「使うべきでない機能はそもそも入れない」で、これは正しいが、 後出しじゃんけんじゃないと無理。 >>186 言うてRustってC++で廃止されたauto_ptrを焼き直しただけだろ。 ヒープの生存期間をスタックと連動させるのはいいが、それはCでも書けるしCだと基本だった手法。(ただし手動) だからRustで生成されるコードはC++でも書けてしまう。 そしてRustは境界チェックがある分だけ遅い。よって最終的に勝てる理由がない。 この点FireFoxの連中は大馬鹿もいいところで、スピード競争してるのに速度優位性がない言語を選んだ時点で自殺だった。 RustはCの代替になろうとしていて、勿論ネイティブバイナリを吐くわけだが、 これを潔く諦め、Cのコードを吐く(TS/JSの関係と同じ)だったら、覇権とれたかもとは思うけど。 この方法だと組み込み全分野に無理なく浸透していけるし。 (ただしこれだとC++の代替にしかならないから気に入らないのだろうけど) RustでOS書こうとしてる馬鹿もいるだろ。誰も使わないよ。 Linuxより速くて小さい物を提供出来る技術的理由がないし、 仮にそれが出来てもCでも書けてしまうからLinuxももっと小さくなり、永久に追いつけない。 Rustには生き残る理由がない。 このおっさん勢いあるスレならどこでも湧くな。そして偏った知識で見境なく喧嘩ふっかける。かまってちゃんが過ぎる。 >>187 そこまで無知だとは思わなかった 叩きたいならばまずは知識を身に着けないと恥ずかしいよ >>189 エコーチェンバーが欲しいのなら他言語スレに出てくるべきではないよ。 Rustが提供してる機能は結局のところ、プログラマの補助でしかない。 Rustで書かないと実現出来ないコードなんて存在しない。 元祖馬鹿向けCはJavaで、大ヒットして覇権を取った。 ただし関数ポインタが無かったのでGUIには全くフィットせず、そこは全滅してる。 とはいえ覇権言語であり、現在でも1/3はJavaだろ。 2代目馬鹿向けCがGoで、これもそこそこヒットしてる。(とはいえC/C++の規模からするとゴミだが) RustなんてGo以下のゴミだし、そもそも人数は馬鹿>>>選ばれし勇者なんだから、 ずっとGoよりもゴミのままだと思うけど。 んで、元祖選ばれし勇者にはC/C++で十分だし。 俺はRustはC++のコーディングルールの一部になると見てるし、そうなる事を望んでる。 >>190 C/C++の欠点はメモリ安全性等の欠如により発生する欠陥の多さであるとグーグルとマイクロソフトが意見を同調している そこへ現れたRustはコンパイルが通ればメモリ安全性やデータ競合ゼロを保証するため彼らにも歓迎され用いられている >>191 C/C++の欠点は「馬鹿が『ひとりでも』混ざるとどうにもならない」事だよ。 ただ、静的解析で何とかなるものなら、「全部入り」のC++にもいずれは導入される。 現在C++は3周遅れ(9年遅れ)程度だから、 9年のうちに優勢になれば勝ちだが、これは多分無いでしょ。 >>192 ところがC++には不可能 Rustには簡潔な借用ルールとライフタイムがあるために成立している さらにRustにはunsafe操作の分離という導入もありこれが安全性の保証に大きく寄与している 次スレまで待とうかと思ってたけど流石にワッチョイスレ作った方がいいか? 完全にスレが崩壊してる >>193 > ところがC++には不可能 『今の』C++にはね。 ただ、C++の場合は少しでもその方がコード効率がよくなる、とされると採用される。(ので良い物はいつか採用される) それが「全部入り」 > 安全性の保証 要するに補助輪でしかない。Rustのは全部これ。 > 簡潔な借用ルールとライフタイム これは俺は筋が悪いと思ってるけど。 プログラマに生存期間をマニュアルで管理させてるだけ。(これはCと同じ) そしてRustの場合はこれの整合性を静的に解析出来る。(これはC++にはない。が、コンパイラ側で対処出来る話。そのうち導入される) だいたいそもそも「貸し借り」なんてやってる事自体、 一般的プログラミングにおいての生存期間と合致してないからであって、根本的に筋が悪い。 そもそもプログラマは管理したいとは思ってないから、GCの方が筋がいい。 GCだと駄目な件については、例えば以下なら、(このブログは有名なので色々言われてるようだが) https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f?gi=bd6f6b9c5be3 そもそも大量の生存オブジェクトが存在する場合はGCには不向きなので、 Goについてなら例えば「GC非対象の変数宣言」構文が用意出来れば済んだ話。 (この思想がGCとフィットしないから一般的に導入される事はないが、 VC++ならnew/gcnewでGCなし/ありを切り替えられるし、俺はこれで十分だと思うよ) まあ心配しなくても、所有権の貸し借りが素晴らしいってことになれば、C++にも確実に導入される。 そのときRustは死ぬよ。その猶予が9年間。 >>196 合成の誤謬ってやつだね C++は全てを含むから最強 あとはC++から必要な機能のみを抜き出せないユーザーの責任 完全チューリングマシンでもやっとけ VScodeで自前のパッケージを使おうとしたら、importの追加のクイックフィックスが出ないんだけど これって昔からだっけ? あ、違うわ プロジェクトのルートに置いてると /cmd/internal 以下のパッケージは参照できないみたい なんだこれ?こんなルールあったっけ?1.17.7 外部パッケージの参照の仕様はまあ仕方ないんだけど なんで内部パッケージで相対参照できなくなったんだろう どっかにブログとか理由の解説ない? ディレクトリ名とpackageでの宣言、二重に記述しないとまともに動かないパッケージ名ルール 物凄く不満 それでいてcmdとかのディレクトリだろうがmainはmainパッケージだし 一貫性よりも何か重要な理由があるのか? ITの9年は長いでよ、ロートルには短いかもしれんが。 そして30年という長い年月を持ってしてもC++はLinuxカーネルに入れなかったのにRustは入った。この違いよ >>202 > ITの9年は長いでよ、ロートルには短いかもしれんが。 長いという程長くもない。お前もオッサンになれば分かる。まあこれはさておき、 実際、現在のプログラミング言語のアイデアは既に80年代に出尽くしており、 今はそれを実装していってるだけ、とは言われてるだろ。言う程進化はしてない。 Rustだって何一つ「新しいアイデア」はないだろ。 > Rustは入った ググってみたが、まだforkして勝手に起こしただけじゃね? > https://japan.zdnet.com/article/35174333/ > https://thenewstack.io/rust-in-the-linux-kernel-good-enough/#: ~:text=When%20we%20first%20looked%20at%20the%20idea%20of,the%20standard%20C%20normally%20used%20in%20Linux%20development. 多分知らないのだろうけど、オブジェクト指向最盛期(2005頃)には、 ・Linuxのコードを『安全な』オブジェクト指向で書き直そう! というプロジェクトはあった。今はググッても出てこない程跡形もないが。 これと同じだよ。 安全に書き直したコードは、書き直してないコード(既に世界中で使われてる)よりバグが多いから意味がない。 この反省を踏まえてRustは「書き直すわけではない」というスタンスのようだが。 LinusはC++の依存性を持ち込む文化を毛嫌いしている。だからC++は入らなかったが、Rustも同じ。 Rustのコードを入れれば、Rustが読み書き出来ないと参加出来なくなり、つまり開発人数がコミュニティ規模に比例して小さくなってしまう。 今現在のRustのコミュニティ規模なんて、C/C++からすると多分4桁くらい小さいだろ。それは開発人数を1/10000に削るのと同じ。 (C++ではコードそのものの依存性が問題だが、Rustの場合は他言語への依存が問題) 馬鹿じゃなければやらないし、Linusは馬鹿ではないと思うけど。 まあRustの連中はすさまじいエコーチェンバーの中で生活してる事は分かった。 Rustスレで相手してもらえないからってこっち来るの止めてもらっていいですか 何を勘違いしているのか知らんが、俺のこのスレの直前の書き込みは>>104 cppの話はcppスレでやれよ。 しかしgcnewってC++/CLIの話じゃないの? gcnewってなんだこれ、.Net専用とはいえなかなか邪悪な代物だな…… >>196 それは知識が足りていない 借用ルールの借用とは当然ポインタを含む概念でありC++でも借用は普通に行われている そして借用をよく見ると読み取りのみの借用と書き換えもありの借用の2種類がある点はどの言語でも同じ 読み取りの借用がある状況で書き換えの借用を許せばデータ競合が起きることはわかるだろ? もちろん書き換え借用がある状況で読み取り借用を許してもデータ競合が起きうる 一方で読み取り借用だけならば複数の読み取り借用を許してもデータ競合は起きない つまり『multiple reader XOR single writer』となりこれが借用ルールだ もちろん全てのプログラミング言語においてこの借用ルールに違反するとデータ競合が起きうる Rustはこの借用ルールに違反がないかどうかをコンパイル時に判定できる言語仕様となっている だからRustはメモリ安全性だけでなくデータ競合安全性も保証することができるわけだ 最近他のどのプログラミング言語スレいってもRustの書き込みあるな 飛ぶ鳥を落とす勢いとはこのことか そういえばJavaが出現した頃、C++erがよくJava厨に噛み付いてたっけ >181 >186 >187 >190 >191 >193 >196 >197 >202 >203 >208 >210 >>96 荒らしに反応するやつも荒らしだからな。誘導だけしろよ。 >195 早いところワッチョイ立てようぜ。 NGが捗る。 >>96 読んでみたが、なるほどここと同じような話が展開されてる。 ただ、C11に移行しようとしてるじゃないか。 >>202 > https://mevius.5ch.net/test/read.cgi/tech/1638086359/542 > トーバルズ氏、Linuxカーネルを「C89」から「C11」コードに移行する準備 > https://japan.zdnet.com/article/35184296/ このペースならあと10年はRustなんて入らないね。 >>208 > それは知識が足りていない これはその通り。俺はRustやる気はないし、借用だ何だかんだの顛末を見て、様子見する事にした。 C++で既に慣らした奴ですら戸惑うのは、 自然な(直感的な)ライフタイムと言語の管理機能がマッチしてないからだよ。 そもそも俺はCでもメモリリークに困った事はない。 ただこれは「困らない範囲でやってる」(=ごくごく安全運転に徹してる)からであり、俺が賢いわけではないが。 この辺の「安全運転を強いられる」のが嫌でC++的にやりたいのも分かるし、Rustも良い実験だとは思うが、 余計な事を考えて、しかもそれでコンパイルが通らない事に悩まされるのは、そもそも設計が悪いからだよ。 つか、そんな事で悩むくらいならGCの方がいいから、実際ほぼ全部の言語はGC持ってるわけだし。 GCの問題点は色々あるけど、discordについては、Goに「GC非対象」を明示する構文があればGoのままで行けてたはず。 何も考えたくないんだよ、っていうGCの思想に反するけど。 Goはポインタのキャストって出来たっけ?出来るのなら、自前で大きめに確保して(数百MB)、 そこから小分けするmalloc/freeを用意してやれば済む。(現行の機能だけで出来る) システムプログラミング言語だ!OSだって書けるんだ!って言ってるんだから、まあ何とかなるんだろうけどさ。 >>207 魔合体されてるVC++が見た目異様なだけで、 gcnewは単にgc対象ヒープから取るだけ。使い方はGC言語のnewと同じ。 (&*が既に使われてるから%^になってて初見で拒絶されるのは仕様) >>211 96読んだ。俺は移動に同意でいいが、移動する権利は相手に与える。 つまり、レスが投下されたスレに俺もレスを投下するから、 俺にレス付けるなら、やりたい方のスレでレスしてくれ。 >>212 全てのプログラミング言語の中で コンパイラメッセージが最も親切でわかりやすく修整点も具体的に指摘してくれるのがRustコンパイラ この状況でどうしてもコンパイルが通らないのだとしたら知能がよっぽど低いのではないだろうか? 標準的な知能があれば問題とならないような点でつまずいたのかね >212 >213 >214 >>96 とっとと行け。スレ違い続けんな。 >>217 Goに限らんけど俺の場合は実際に動くコードの載ってる本で写経しつつ読み進めるのが一番短時間で覚えるみたい。 俺って頭じゃなく体で覚えるタイプなのかも。 結局、文法的なものは他の言語触った経験あれば新しい言語も難しくないんだけど、キーワードの要不用やライブラリやそれの使い方とか、その辺記憶するのが一番面倒。 >>218 やっぱ自分の能力次第だよな。 俺はなんかサイト一個作ったほうが覚えられそうだから作ってみるわ。 何作ろう 標準的なソースコードを集めたコードサンプル集とかあればいいんだけどな。 ハイエンドというほどじゃないが、みんなのGo第二版はよく参考にしてる flag使ったときとか でも言いたいのは多分、ファイル読み込みとかごく基本のコード断片だろなー テーブルドリブンテストはなんか標準かでGenerateされるようになったね テスト対象の呼び出しまで完璧にサポートされてて便利すぎる ジェネリクス使ったmapやsliceのユーティリティが乱立するのかな やっっっとジェネリクス医薬品きたのかよ どれどれどんな塩梅よ >>225 よっしゃ! そしたら1.17入れる準備するか。 >>229 使いにくいインタフェースで筋が悪いな あと多段適用するにしても途中で毎回配列生成は無駄すぎる GoCVのWindows版一生動作しなくて泣いてる 動作してる人がいたらmingwとgocvのバージョンの組み合わせとか教えてほしい >>231 解決した gocv 0.28.0 mingwgcc 8.1.0 go 1.8 で動いた 今更案件に採用したいとの連絡が来やがった。 もう他に決まっちゃったよ… go案件一回だけ行けたことあるけど バージョンが古くてきつかった記憶あるなぁ 下手にでかいシステムだとそういうのあるんだよな もう go modules 無しで開発できる自信がない… 構造体のブランクフィールド struct { _ int } って、どこかのソースで使ってるのって見たことある? 1.18 で ~T って、T を実装している型という認識で正しいのかな? 1.18 の言語仕様読んでるけど ジェネリックスいらんわホントに HTMLコメントでは書き足りてないとか、ホントにホントに… >>239 ジェネリックス入れる上では仕方のない事なんだけど、 型関係の言語仕様が山になって追加されてた spec の単純行数にして 1.17 - 2823 行 1.18 - 3265 行 (+442行) これからガンガンでかくなるはずなので、これに耐えられないなら早く逃げてくださいね お疲れさまでした >>239 ライブラリ開発者くらいじゃないのか? 欲しがってるのは正直、一部の開発者だよな そのために仕様を10%単位でブクブク肥らすのは許容できるトレードなのか? >>242 通常のユーザーがジェネリック使うの強制なんだっけ? ライブラリアン専用なら気にする必要無い気がするけど。 >>243 初学者が仕様書を読むとき、ハードルがかなり上がってしまう 何故かというと、至るところで型統一やらジェネリクスの用語の汚染が進んでいるから もう、初心者には1.17の仕様書で勉強させるべきに思える >>244 初学者は仕様書読ませるのがそもそも間違い。 入門書読ませなさい。 >>245 s/初学者は/初学者に/ typoすまんね。 あと珍妙に思えるような気もしなくもない文章が The result of constraint type inference is final substitution map M from type parameters P to type arguments A where no type parameter P appears in any of A. 引数Aから型パラメータPがなくなるまで置換するマップMを制約型推論の最終結果とする、でいいのかなあ >>245 あー、自分基準で初学者としてCのベテランレベルを想定していたわ gccでインターネットサーバを書いてた層 半日でだいたい理解して三日でアプリを組み始めた プログラム作る側からすると便利なライブラリが増えるからいいと思うわ map/reduce/filterみたいな操作をたくさんするとき、マジで面倒だったしジェネリクスあればいろんな場面で助かる >>247 意訳すると型パラメータの方程式を解いた結果の制約集合が推論結果です、ということか もったいぶった文章だな Rob pikeのチェックは入ってるのか? >>251 1.18の言語仕様の一部 その文は、Constraint type interface の中頃 とにかく読みづらい仕様書になっちまった! と言いたい そうですね もうGoを使うのはやめたほうがいいですよ^^ システムプログラミングしかしてないので あんまりいらないけど Web系とかはあったろうが便利なんじゃないだろうか コレクションの中身が何の型かって基本的なことがわからないのはキツいよ Goでコレクションなんか使うか? プロダクション運用してるけどsliceとmapしか使ったことないわ >>248 ベテランでも仕様書は読まないだろ。 普通はクイックツアー -> やりたいことのサンプルコードだと思うわ。 >>258 普通は仕様書からチェックすると思うが CでもC++でもJavaでもGoでも あれ?C#の言語仕様書って見た覚えがない… >>259 ああ C#はマイクロソフトのヘルプで見てったから文法書形式のは覚えがないのか JavaScriptもMDNばかりで仕様書をよんだことないや >>259 ANSIとかISOとか持っているやつがそんなに居るかね。 >>261 CとかC++やってりゃ赤とか緑とかARMとか持ってないか? もっともインターネット以前だけど たまには仕様書も読みなおすと新鮮 いつの間にか妙ちきりんなルールが追加されてたりするし _ &= flag というように、算術代入の左辺に空白識別子は置けません、とか誰得? NOOPだとばかり思ってたけど変わったのか(わざわざ確認する気もない 日本の製造業何十社から、トップが集まった、MISRA-C 研究会でも言ってた 日本には、C の仕様書に詳しい香具師はいない! だから、仕様書で議論する事ができないので、 組込み開発者におくるMISRA‐C:2004―C言語利用の高信頼化ガイド、MISRA‐C研究会、2006 という本が書かれた これが実際のコーディングルールのバイブル 抽象的な仕様書で、議論をしない事。 必ず、具体例・コードで議論する事 これが大原則 仕様書で議論するのは、現実的じゃない。 江添のC++ 本を見ても明らか 仕様書を表現した無数のコード例が書いてあるけど、細部は省略しますばっかり。 細部まで突き詰めていくと、切りがない 江添レベルの人間が、日本に2人もいないので、仕様書で議論することは無理 >>266 そこは有る無いという話ではない そこはRustの方が使いやすい 特にトレイト境界がありがたい 最近マシにになったと思ったが我慢できないのかな? Go Nimスレに閉じこもっててくれ そこは好きに使っていいから 個別スレでは大人しくしといて >266 >269 >270 >96 餌与えんな。 >>274 ttps://go.dev/ref/spec じゃないの? 定数、変数、型やらの基本的な言語仕様で型パラメータやらコア型とかのジェネリクス関連の概念も持ち込んで記述する必要がある けれどもライブラリ、それも今までinterface{}を引数に持ってたような関数を書いてたライブラリにしか関係ない概念を何故か皆が学ばないとならなくなった 単純に仕様書の行数から、学習コストは10%悪化したと見なせる ジェネリクスは項として別枠に記述して、そこで定数やらでのジェネリクスの影響について書いてもらいたかった >>277 いや、無茶振りだとは分かってるただの愚痴 愚痴ばかりだから老がいとか言われてるんだよな Goの長所はシンプルさ その長所を劣化させてまで今さら導入すべきものではない どうしても必要なものならば最初から仕様に含めるべきだった ロブパイクが実質リタイアしたから通ったんじゃないかな 一応、大昔からジェネリクスは入れるとロードマップで予告はされてた ジェネリクスなんていらん、ていってるやつのほとんどがロートルジジイばっかりでわらう いや、ジェネリクス導入が遅すぎたこととそれが中途半端であることを問題視する人々が多数派 そのために全体のシンプルさを失い更なる中途半端な状況を招いている コンパイラの実装を大幅に変えなくていいから この仕様に落ち着いた感はあるよな 大体がJava5でジェネリクスが導入されてから、自分で書いた奴ってどれくらいいるの? 居るなら自分のプロジェクトリポジトリ晒してみ? とか書いてから ArrayListに散々お世話になっていながら、その言いぐさはないよなーと反省 golang.org/x/text/encoding/japanese でshiftjisをデコードすると 不正バイトはU+FFFDに変換されるんだけど エラーを返してほしいときはどうすればいいの コードを見ても変換失敗時にエラーを返すロジックないし ルーン '\ufffd' の変換結果をdstから探したら? [..., 239, 191, 189, ...] という並びがあればエラーだと思うけど https://go.dev/play/p/8ALF1MMIQPz だめだplaygroundのURLがどこで間違ってるのかわからん playground側の問題かもしれんね 別のサービスでコード共有したら? https://github.com/golang/go/issues/18898 もともとエラーを返すようにしてたのをFFFDに置換するようにしたのね > ルーン '\ufffd' の変換結果をdstから探したら? それしかないかー >>293 5chはタブレットで見てて、コードを書くのはPC 手打ちで書き写してるせい lとかIとか使う邪悪なシステムが悪い fffdをバイトにデコードしてるだけだから上の配列値があればいいかな >>285 ジェネリクスなんて糞みたいなもののためだけにビルド速度落としたらgo使う意味がそもそもない。 golangの機能追加によるビルド速度低下なんて他の言語のコンパイルの遅さに比べれば毛の生えたようなものでしょ・・・ ビルド速度とは関係ないが、1.18から関数の呼び出しがスタック参照ではなくレジスタ引数で呼べるようになったので 実行速度が5%-15%改善してる。 否定的意見じゃないんだけど レジスタ渡しって%単位で効くもんなのかな? 実処理の5-15%がスタック渡しに費やされていたって話だよね 速度的にはキャッシュに乗る乗らないとか色々ありそうだから 定量的に測るのは難しそうだが そもそもマシンコードの関数呼び出しがレジスタ経由でしょ なので普通になっただけかと そんなわけない、レジスタに乗らないデータは普通にスタックポインタレジスタでスタックに格納される。golangが スタックだったのは実装が簡単になるからという理由が最も大きかった 関数の引数をレジスタ渡ししても その関数内で別の関数を呼ぶときにスタックへ退避しなければならない だからC言語でも引数はスタックに積んで渡す たしか処理系がどのABIを採用しているのかによるんだと思うし、そんな十把一絡げにC言語やらの話を一般化されて話されてもツッコミどころが多い __fastcall宣言とか使うとまたさらに挙動かわるし 少なくともLinuxのCでは第6引数まではレジスタで渡すよ 6個以上の引数なんてクソコード以外では存在しないから 実質レジスタ経由だよ windowsは知らん cみたいに他からも呼ばれるような言語の場合はスタック積みじゃないかね。 ABIの互換性の便利さと比較して、キャッシュ考慮したらそこまで性能出るとは思えんし。 開発者が実装が簡単だったからと言ってるのでレジスタ数とか、GCCの第六天の魔王とか関係ないよ 開発者が実装が簡単だったからと言ってるのでレジスタ数とか、GCCの第六天の魔王とか関係ないよ もう30代くらいの若いお父さんだと菖蒲湯知らないんだな 子供より先に「ネギが入ってる!」ってリアクションするもんだから笑い堪えるのに必死だったわ 漏れら極悪非道のageブラザーズ! 今日もネタもないのにageてやるからな!  ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ∧_∧ ∧_∧ age (・∀・∩)(∩・∀・) age (つ 丿 ( ⊂) age ( ヽノ ヽ/ ) age し(_) (_)J GoLandとか使ってる人いるの? Goを使う開発って腰を据えてGoだけがっつり書くという状況が少ないからクソ非効率だと思うんだが つまりGo以外も書けるGoLandは効率的ということ ちょっとVSCodeに不満を感じてなくて他に目移りしてないんだよな 最近まともなレスが無いけどGoってやっぱ廃れたんだね Ruby使いで良かった(^_-) yoshikiはもうx japanのアルバムは出せないみたいな事言っちゃったしな >>321 全く売れないだろうしな 今更アルバムとか時代遅れ もうGoは終わりだな 俺はこれからPHP使いになる。じゃあな 俺はGo使いからC使いになるよ 結局全てのことはCで出来るんだし、森羅万象の神になるためにもCを極めるよ _ ー――--_ ._ <;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r ´;;;;;;; ̄Y / ̄/\ヽ;;;;/;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Y;;;;;;;;;;;;;;;;| Y / \.\ \;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Y;;;;;;;;;;;ノ t――/ ;○;\ \/|;;;;;;;;;;;;;;;;;;;;;;|―イ / { "' ' \\ .|;;;;;;;;;;;;;;;;;;;;;;| / { . ;○;\\ヽ;;;;;;;;;;;;;;;;イ Y Y , , , , ヽ;;;;;;;;;;;;;ハ / \ ェ‐-ュ レ-‐-イ ヽ // Y .`´ __ Y Y /  ̄| レ―― ̄ ̄入_ _ノ | / <  ̄|  ̄ ̄ | .ノ / | メ / < .|イ / | / < __| _ / _― ̄ _-ー ̄ \ -―ナ √ V \/ / / /V く / ./ V \ / V \ / /⌒ヽ {:: :{ _\{‐…‐-.. .,_ 、丶`:: :: :: :: :: :: :: :: :`: 、 /:: :: :: /:: :: :: :: :: :: :: :: :: ::\ /:: :: :: :: √ :{:: :: :: :: :: :: ::V/:: ::ヽ /:: :: :: :: ::.{:: : {:: :: ::{:: :: :: :: :V/:: ::‘, _.厶 --― ¬:゚, :: :: V/:: }:: : }、\:: } Ξ, , , , /////, , }!:{ ―- V/ }:: : }::\\ Ξ/////////// }!::〉 ,xぃ、V:}:: : } :: :ハ;_:〉 Ξ//ⅣムV/Ⅳ// }!´ ′ん心,}:: :,゙、 ::{ Ξ /{  ̄  ̄ Ⅵ/ }! 乂ソノ::./ ノ:: { Ξ/「 0 < }/ }! :.:./::_/ィ:: ::! -‐㍉ }/.}! _、-''⌒`ヽ、{ :: ‘,:\ / ’, \ / }'/ \ :‘,ー- ′ -‘, __{ ‘, ::`:: ┐ ,′ ./ }___〈 ‘, ‘,` ー┘ ,′ { ./ ハ ‘, ノ ‘, 〔_ { { { / / 〔 ̄(‘, 丶 _∠ __ ′ 〔_ { 丶 ー 1 ./ / / }'T !ー^'ー'"{ ', 〔_ / ` ‐ }/ / / / |} . { { ‘,⌒i GopherくんがキモすぎたからGo言語廃れちゃった…… 見たことあるなと思って検索してみたら2012/06か (o゚Д゚)=◯)`3゜)∵ これと組み合わせられないかと思ったけど難しいな ていうかさ 仮にゴーがこのまま静かにフェイドアウトして廃れてしまったらきっと 「やはりマスコットがキモすぎたのが敗因か」とか言われるに決まってるが、逆に 何かの手違いでうっかりプログラミング言語の王者となった場合にもやっぱり 「マスコットがキモすぎたのにもかかわらず、これだけの人気を獲得したGoとは!?」とか言われちゃうんだろう どっちにしてもキモいとしか思われないゴーファー君かわいそう 10年ぐらい前なら美少女化とかしてイラスト描いてる人いそう D言語のマスコット凄くかわいかった 何で流行らないんだろう マスコットはネタになるくらいだしまあどうでもええけどな LinuxのTuxやJavaのDukeはそこそこかわいいけど、Hadoopはヤバキモいゾウにも関わらずかなり使われてるし とはいえやっぱLispエイリアンくらいにキモかったりする許せないな・・・ 地溝油 製造方法 マンホールの蓋を開け、下水道内の黒く濁り、赤みを帯びたのり状の物体を掻き出し、一昼夜かけて濾過した後、 不純物を凝固させる薬品と共に煮詰めて精製、沈殿、分離など複数の工程を経て、再生食用油に仕上げる。 悪臭を放っていた物質は、この工程によりほとんど無臭になり、腐敗したドロのような廃棄油は澄みきった食用油となる。 見た目や臭いだけでは地溝油と本物の食用油を見分けることは困難であるとされる。 ただし、糞尿を加工して生産しているのではなく、レストランからの下水などに流れ込む油分を地溝油の生産に使用している。 Rustスレ→毎日論争が起こるぐらい盛り上がってる Goスレ→言語とは関係ない雑談、保守レスのみ 俺悲しいよ。Goが覇権取るんじゃなかったのか? >>294 utf8.ValidStringというのは使えないの? tutorial勉強中に出てきたけど 言語仕様をそれなりに語れる言語って実質rustしかないからな C/C++の全盛期を思い起こされる いつの間にか世間じゃ1.18の時代なんだなぁ Lambda の Go 実装を試しながら このスレって何を語るんですか? プログラミングに関係無いスレですよね? 今は色んな現場に数年前にGoで作られたLambdaがたくさんありそう 1.11とか1.13ぐらいの Goは互換性高いからいきなりランタイムのバージョン上げてもまず問題ないでしょ AWS の Lambda Node.js runtime の EOLに疲れたのでGoにしていってる話、とかあるね インタープリタじゃないので実行時に最新のランタイムで動くことを強制されないからだって 他の言語は半年とかのスパンでランタイムがバージョンアップされその度に確認やらしないとならない、という主旨 AWS側でランタイムの検証負荷が高いって話? Goだとそのあたりの責任は各利用者に丸投げできるわな。 いや、Go だけ特殊でLinux用にコンパイルした実行イメージをzipしてデプロイするのと、Lambda実行環境との依存がnet/rpcという枯れた技術しかない そのためバージョンアップの影響を受けそうにないという理由 つまりランタイムがないんよ Lambdaはコンテナイメージがサポートされたから他の言語も塩漬けできるようになったけどね Genericsが出て暫く経ったので聞いてみます。ʕ◔ϖ◔ʔ イテレーション可能な汎用的なコレクションをmap/reduce/filterなど高階関数で操作できるGitHubスターが多いライブラリは何ですか? >>383 A Lodash-style Go library based on Go 1.18+ Generics (map, filter, contains, find...) https://github.com/samber/lo >>385 これはセンスないわ エラーを扱えないしメソッドチェーンもできない AWS Certified Developer - Associate の教科書に書いてあるけど、 AWS Lambda で、deploy package のサイズの上限が、 ZIP は250MB だけど、Docker コンテナイメージは10GB AWSベースイメージである、Amazon Linux 2 以外にも、 Alpine, Ubuntu などで、カスタムランタイムも作れる Ruby が簡単 >>386 https://github.com/elliotchance/pie これはチェーンが出来る。 多くの言語でコレクション操作中のエラー状態を返すという動作はあまり見ない、Rustなんかでもそう。GitHubスター数多いから挙げたが、チェーンもGoの模範的な1行の長さなどがあるし、Goはメソッドチェーンそのものをあまり勧めていない。(慣例的にエラーを2番目の戻りにするから) エラーを扱えて、チェーンができる言語ってなーに? >>388 RustはResult型やOption型によってチェーンでエラーが扱われている goはそもそもエラーを扱う気概にかける言語だからどうしょうもない 毎回いちいちエラーコード返すのが作法とか何時の時代だよって感じだ >>390 「例外」がないからGo言語はイケてないとか言ってるヤツが本当にイケてない件 という記事があるから、それに対して反論してからどうぞ >>388 即時評価だね0点 百歩譲ってfilterやmapはエラー扱えなくてもいいとしても、foreachでエラーを考慮しないのはダメでしょ Rustも例外が無くエラーを返す点でGoと全く同じだが OptionやResultといった代数的データ型で返すため抽象度の高い取り扱い及び記述がむしろシンプルさと利便性を両立させている 例外を無くした同じ方針なのにまるで原始時代への戻りと未来への発展の差を感じさせる異なる結果となった 例外はgotoと同じだぞ 現代のネットワークやデータベースといった外部依存が沢山あってエラーがありふれる世界にはそぐわないからGoの値で返す方針は正しいよ Goにあと20年のキャリア賭けてみても大丈夫かね。 未経験可の案件あるから飛び込んでみようと思うんだが… 40ちょいだからあと20年は戦えると嬉しいんだが。 >>394 Web系のエラー処理はオールオアナッシングが基本であまり細かい個別のケアが必要ないから、むしろ例外向きなんだよ >>392 遅延評価とは反復を使い込んで消費する関数を呼ぶまで効果がない事です。どこをどう見たら即時評価だっていってますか? 明らかにチェーン生成で遅延評価です。 func Of[T any](ss []T) OfSlice[T] { return OfSlice[T]{ss} } それと上記ライブラリにはforeachなんてファンクションはありません。Rustのforeachが副作用を伴う操作が出来てしまうが過去の互換性を 維持するための現在の仕様のことを見聞きして言っていますか?通常多くの言語や高階関数操作が出来るライブラリでmapとforeachの違いは 値を返すかどうかの違いでありエラーを返せるかどうかではありません。またRustがtry_for_eachが存在するのもあくまでも利便性のための 例外であり、普通は特に高階関数操作中のエラーが起こることこそが例外でダメなコード設計です。 もしコード中でコレクションに含まれるデータにより例外エラーを伴うようなコードを乱造しているのであれば”大きく”反省してください。 それとも全く分かってないのに言葉遊びしている?印象を受けます。「foreachでエラーを考慮しないのでダメ」の理由を示してください >>397 rustのitertools::foreachはそもそも遅延評価じゃないし、過去の互換のために残されているのはその通り。ドキュメントに明記されている 遅延評価じゃなく積極的な評価だから例外が考慮できるといえるがrustの真価は高階関数操作が共通的であれば最適化されること。goが同様の操作を最適化するかどうかは知らん GoはそもそもGCがあってランタイムが重たい高水準言語で、ローカル変数でも必要ならヒープに確保するし、 GCどころかヒープすらなくても動くRustとは最適化の文脈が違いすぎて・・・ アホか、レジスタ数が限られてる現代未来において必要ならローカル変数なんかヒープやスタックに確保するのは当たり前だ。 そもそもマルチタスクOSで動く今のプログラムは普通に変数はヒープの間を行ったり来たり ランタイムが重いんじゃなく、ランタイム大きい。最適化の度合いも近代的な言語で大手企業が支援あれば大差ない。 そんな事やってるからRustが嫌われるんだぞ、馬鹿野郎 Rustは低レベルなシステムプログラミングに使えることが目的な特殊な言語なので >>397 ストリーム系APIでいう遅延評価というのは一般にいくつかのレベルがある 例 : items.a().b() 1. 最終的に結果を列挙しようとする段階でaとbの操作を実行する。実行順序は、aの操作をitemsの全ての要素に対して実行した後にbの操作を全ての要素に対して実行する。 2. 可能な限り列挙を繰り返さない。可能であれば、1要素毎にaとbの操作を実行し、次の要素に進む。一時バッファを使用しない。 3. 実際に要素が必要になるまでitemsの各要素を生成しない。つまり無限に続くシーケンスの実装が可能。 例えばシーケンスの順序を逆転させるような操作は一度全てを列挙しないといけなかったりするから、普通はこれらのハイブリッドな実装となる。 >>388 で実現されてるのはこのレベル1までだね。 >>397 見落としてるだけだと思うけど、 >>388 にはEachがあるよ。エラーを扱えない欠陥品だけど。 半分禁じ手に近いけど、deferでrecoverするという手も無くはない あれは日和ったと見るべきか >>402 遅延評価と「無限に続くシーケンスの実装」はまた別問題だ。ほとんどのプログラムはfilterやmapも有限長だけで十分機能する。 Pythonのコルーチェンyield中断と同じく、それを基にしたRubyの.lazyや、さらに進んだC#のLINQなどは無限長の操作を可能にするが Rustの無限長イテレーターはRangeやstd::iter::repeatにおいて無限長を扱えるだけであり、yieldはまだ実験的。 というか迷惑だからRustスレか言語比較してるスレでやって攻撃的な人格疲労しろよ >>405 俺はRust信者じゃないぞ? 十分機能するかどうかは個人の感想の問題だが、いちいちリストのコピーが発生するから非機能面では十分に問題になりうる >>406 そうか?チョットでも知ってればGoはyieldなんてキーワードはサポートしてないので安易な無限長をサポートするわけない。 最初の何も見ずforeach言ってるRustバカと一緒で、コレクションに含まれる高階関数操作で例外を考慮する状況がなぜ正しいのか説明できていない。 それだったらまだ蛇足的に挙げた無限長が扱えない事のほうが欠点だ、ほとんどの状況は高階関数系で例外なんてforeachでもEachでも考慮しない 上のライブラリはチェーン連鎖でコピーが発生するのはその通りだが、例えばfilterにmapをつなげて最後にcollectするような操作は上記の遅延評価や 無限リスト、そして例外とは何の関係もない。言語的な宗教戦争をやってるバカようにしか見えない、とてつもなく迷惑この上ない行為だ >>407 無限リストを扱うための前提として要素毎のストリーミング処理ができることは必須だから全然関係なくないぞ なんか勘違いしてるようだが、俺はGoを貶しているのではなくただ>>388 のライブラリがヘボいと言っているだけだ 別にyieldがなくたって今のGoで無限リストは実現できるよ Goならyieldみたいな妙なことしなくてもgoroutine内でループしてチャネルで送りつければいいだけだもんな 妙でない==基本的な機能の中で説明できる yieldなんてgoto並みに不自然じゃん >>405 それは君の理解が間違っている > Rustの無限長イテレーターはRangeやstd::iter::repeatにおいて無限長を扱えるだけであり、 その部分が完全にウソ Rustのイテレータは誰もが自由に任意の無限長イテレータを作成可能 そしてその無限長イテレータに対して任意の別のイテレータを好きなだけチェーンさせて動作可能 これはRustのイテレータが中間生成物(リストや配列やベクタ)を作成しないため可能となっている Goで整備するときもここが重要なポイントとなってくる 無限リストって実際に無限長の何かを使うことは滅多になくて、あくまで遅延リストとして適切に実装されているかどうかの判定基準なんだよね 無限長リストを扱える構造になっていることは、メモリに乗らない巨大なファイルを一行ずつ読むような、文字通りストリーミング処理が必要な状況で非常に有用なんだよ 結局2種類のうちどちらを選ぶか、だけの問題 (A) 遅延処理 ・メソッドチェーン時の中間生成配列などを無くせる ・無限長も扱える ・無駄がなく有利 (B) 即時処理 ・メソッドチェーン時の中間生成配列などが必ず必要となる ・無限長を扱えない ・(A)よりも不利 RubyのlazyやRustのイテレータはもちろん(A)タイプ Goでも欲しいのは(A) (B)タイプのものは検討する必要がない Go 2のProposalを見ると https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md > We do not expect approaches like the C++ STL iterator types to become widely used. In Go that sort of idea is more naturally expressed using an interface type. In C++ terms, using an interface type for an iterator can be seen as carrying an abstraction penalty, in that run-time efficiency will be less than C++ approaches that in effect inline all code; we believe that Go programmers will continue to find that sort of penalty to be acceptable. って書いてあるけどまあGoはそういう言語で、そこまで最適化にこだわる言語じゃない 最適化にこだわるひとはRustとかC++とか使うべき >>415 これは遅延リストを否定しているのではない C++のようなゼロオーバーヘッドは目指さないよ、もしイテレータを抽象化するなら実行時のオーバーヘッドを受け入れて普通にInterface使う想定だよと言っていて、 将来的に>>414 の(A)のスタイルのイテレータを導入する可能性は下記の通り肯定している > As we get more container types, we may develop a standard Iterator interface. That may in turn lead to pressure to modify the language to add some mechanism for using an Iterator with the range clause. That is very speculative, though. >>416 つまり将来Go3になる頃には>>414 の(A)がGoでも出来るようになる可能性が残されていると >>417 なんだ、プログラミングは経験者か。 ならGo未経験案件でも収入大幅に減らないならスキル増やすつもりで行っていいかと思うけど。 >>418 案件多いのはPHPなんだぜ涙 >>419 単なるデザインパターンだから今のGoでもできる イテレータのinterfaceが標準化されてないだけ >>421 本当に出来るならばなぜGoではやらないの? 速いし便利だしコードも分かりやすくなることが多いため色んな言語で使われているのに >>422 標準無視のコードで俺スゲーしたい系の人はRustに行っちゃうからだろうね イテレータを使うようにしたら、こんなふうになるのかな? https://github.com/Soft/iter いちいち関数呼び出しすることになるから普段使いにしようとするとパフォーマンス悪くなりそう RustのイテレータがCのfor文と同じ速度が出るのも最適化された設計と実装によるものだもんね あとはGo開発陣のやる気次第 >>424 これはダメだね パフォーマンス以前に、イテレータを閉じる方法がないからファイルをストリーミング処理するようなユースケースに対応できない ちゃんと言語機能の背景を考慮せずにRustを猿真似しちゃった失敗作だね 何をどう見ても許されてないしロシアが核持ってなかったら、 集団的自衛権をもとに連合軍が作られてプーチン政権が倒されるか、ロシアも同盟を集めて世界大戦に発展してるよ >>409 その通り。Goで中間コンテナを作らないようなGeneric版高階関数ライブラリを作ろうと思うと、yieldのような中断じゃなく確かにチャネルの受け渡しになる。 それでfilter->map->collectのようなRust的な中間コンテナを作らないようなコードを書くことになると、中間の加工データの受け渡しはチャネルになるので、Rustで そのままでは安易に並列化できずにrayonライブラリなどを使うより、遥かに簡単にスケールできる並列化まで踏み込む可能性がある。 これをGoogleはパイプライン処理と呼んでいるが、421の言うように1.18はイテレータの標準化とコレクションの操作の一般化を変更に含めなかっただけ やる気というか現代のソフトウェア開発は、世に出たら0から255まで揃ってる訳ではなく、小まめな段階リリースだから おじさんがくるとこうなるのね 本当にこの世から消えて欲しい モックって何使ってる? gomock, testfy, mockery オススメは? >>435 に一票 Goでモックフレームワークが欲しくなるようなら設計と開発スタイルがおかしい カバレッジ100%目指さないの? 共通ライブラリのエラーのパスとか 別におすすめじゃないけどgomock使ってる gomockはinterface{}だらけで静的型チェックが効かないからたまにイラッとする がーん、週明けで確認したらGCPでホストしているサービス二個ともが、のきなみサーバーエラー500で動いてない Memorystore の障害なのか?これは Firestoreのクエリ結果をキャッシュしてるから確かに使ってる あ、よく考えたらGoスレではスレ違いな話題だったスマン ホストしてるのはGoだけど 質問 xxxx_test.go は go test だけで、go build からは無視されるとかって本当? だとすると package xxxx_test とかパッケージを分けるのって意味がない? あー、テストで xxxx をインポートしてる別パッケージをインポートしたいときに、xxxx からじゃ循環参照としてコンパイルできないから意味はあるのか ごくまれに package xxxx_test を作ったほうが簡単に解決できることもあるね *bufio.Scanner とか *os.File といった、interface じゃなく struct な戻り値を返す標準関数で、scanner.Scan() とかの戻り値による分岐をカバレッジしたい 標準関数は関数ポインタによるフックに変更して、モックで差し替えられるようにしたんだけど、関数ポインタのシグネチャが struct を返す形なんで、上記の scanner.Scan() とかを差し替えられない そこで bufio.NewScanner() を直接に使うのではなく、scanner を interface で返すラッパー関数を作って、そのラッパー関数ポインタをモックで置き換えさせることを考えたりしてるんだけど …やり過ぎ?(そもそもこの説明で分かるかな?) そもそも例外なケースのカバレッジのために、そんなクソ複雑なメカニズムを入れるのは、保守性を下げてしまうから本末転倒だろうか? Go的には、差し替えが必要なんだったらScannerを直接使わずに最小限のアドホックなinterfaceを定義し、 それを関数の引数に受け取るかstructのメンバに持たせるのが筋 >>448 うん、そんな感じ https://pastebin.pl/view/d979ea5b 該当部分を抜粋 しかし無駄に複雑なコードかなぁと そこまでする意義はあるのかないのか >>449 これだけ複雑なのに、os.Open() と s.Err() がエラーを返すパスを通せるだけというのは、 コードの保守性悪化に見合うメリットたりえるのか そう感じてしまって悩んでる これが Java ならクラスローダーでプロキシインスタンスに差し替えるという手段で対象コードには手を触れなくて済むから… >>450 そのへんはGo云々というより設計センスの問題だな textLinesがhookを持つのではなく、LoadFromの引数にfilenameの代わりにiScannerを渡して、その実装を提供するのは呼び出す側の責任にした方が良いと思う filenameを受け取る便利関数を提供したいなら、それとは別にLoadFromFileNameみたいな関数作ってFileやScannerをインスタンス化してLoadFromに投げればいい そうすればインスタンス化の部分とそれを使う部分とでテストケースを分離できるでしょ そうだな、設計の話だなあ コードがそこそこの規模になるんだったらとりあえずDI的なことをやったほうがいいよ 普通に自前でScanner作れよ 大して難しい話じゃないだろ 構造体のコンストラクタのコードを見ると必ず構造体のポインタを返していますが、ポインタにするメリットと値を返したときのデメリットを教えて頂きたいです >>454 受け渡しの際に毎回コピーするのではなく同一のインスタンスを引き回すことを想定している場合、 それを利用者に主張するために値ではなくポインタを返すことが多い ポインタで受け取ったものをわざわざデリファレンスしてコピーなんて普通あまりしないからね 構造体をオブジェクト指向言語におけるミュータブルなクラスのように使っていると、コピーされると意図せぬ挙動になりやすい >>453 >>449 見れば分かるがファイル名を受け取ってos.Openして得たFileからScannerを作ってるわけで、これをどうやって差し替えるかという話 >>453 だから、ScannerではなくNewScanner関数をどう差し替えるかという話 >>455 よく分かりました ありがとうございます コンパイルするファイル内に設定値も全部入れたいんだけど、 その場合は設定値だけのファイルを読み込むことって可能ですか? 関数にしてmapで返す感じしかないですか? jsonファイルをgo-assetsとかgo:embedで組み込んで、それをjson.Unmarshal()で構造化データとして使えばいいと思うよ 個人的には設定はビルド時に埋め込むならソース内にjson風にハードコードする派 設定ファイル嫌い 組み込みjsonをデフォルトとして、カスタム設定ファイルは外部のjsonにする デフォルトから取り込んでカスタムで上書き これでjsonからの取り込み部分を一本化できるのでバグを防止できる ハードコードしてると取り込み部分が共有できない (json文字列を返す関数でもいいんだけど >>463 組み込み設定は構造体をハードコードし、カスタム設定ファイルはそれをjson等で上書きすればいいだけ どうせ上書きされるのは極一部の項目だけなんだから、大部分はコンパイル時のチェックによりバグを防止できる >>464 と、思っちゃうよな 構造体定義して、初期化で初期値書き込んで、それとは別にカスタム設定取り込みコードを書く 対して、構造体定義して、設定取り込みコードを書く すると設定取り込みには普通にバリデートも書くから初期化での値バグが起きない >>464 まあ、好きずきの話に近いことは近い ハードコードした設定値をバリデーターにかけてチェックさせる作りなら解決できなくもない でも取り込みの各段階でバリデーションしていったほうがミスりにくいと俺は思うから そんなにバグが怖いならそもそもそんな柔軟な設定ファイル要る?というところを見直すべきでは 汎用的なOSSでも作ってるんでない限り、設定なんぞ環境変数で十分 あとは全部ハードコードすればバリデーションなんか要らん バグが怖いというより、適切なアナウンスかな 設定のどこが、どう不味いのか フレームワークのginでWebアプリ作りたいなと思ってるんですけど、ginの勉強にいい教材ありますか? Pythonでツール作ったことあるくらいで、Goの基礎は一通りやったくらいのスキルです。 日本語ドキュメント見てもいまいちピンときてません https://gin-gonic.com/ja/ gin自体が良くないからいい教材なんか無い Goはnet/httpパッケージを使うんだよ いやGinでいいだろ 今どきnet/httpだけでWebアプリ作ってるとこなんてねーよ Gin+Vueとかで作ってみな 5chにいる玄人()のおっさんに惑わされんな gin、chi、echoどれも薄っぺらいんだから対して変わらない どれでもええわ 月額報酬が最も高い開発言語ランキング 3位は「Python」、2位は「Go」、1位は? フリーエンジニア向け仕事仲介サービス調べ Goは単価高いけどGoだけ出来ればいいってわけじゃないからなぁ ECSとかTerraformみたいなクラウド技術も使えて当然だよね?って雰囲気が全体的にある Goのmapをfor分で回すと順序が不定というのはなんでそうなったの? >>483 将来的な最適化の余地を確保するため。 大抵の言語では、標準のハッシュ表はその内容が変更されない限りは順序が変わらないような実装がなされていることが多い。 しかし、プログラマにそれを期待したコードを書かれてしまうと、内容が変わらなくても順序が変わりうるような実装に将来的に変更したときに既存のコードが破壊される可能性がある。 Goはそれを避けるために順番を意図的にシャッフルしている。 例えば、将来的にはGCがmapのメモリレイアウトを自動的に最適化するかもしれない。仮にそうなればプログラマが内容を変更したつもりがなくても順番が変わるだろう。 Rubyとかは逆に不定じゃなくしたよね。いつだったかのタイミングで。 あれは変な判断だと思ったなぁ。 Rubyの連想配列(Hash)にはshiftっていう変テコなメソッドがあるせいかなあ RubyやPythonの用途なら挿入順でイテレートできるようにするためにかかるコストよりも 利便性が優先されるからじゃないかな Go 1.19 is released! https://go.dev/blog/go1.19 もう出た 今verは早かったな Pythonはordered dictがいつの間にか標準dictになってたな 便利だからいいけど 最近の言語仕様書はDeepLすら受け付けない英文なのはどうにかしてくれんかな ほかにもインターフェース関係の解説でいつの間にか話に出てきてないFileインターフェースが混じってきたり 絶対にレビューしてないよな なお1.17を読んでる(1.18 からはジェネリクスで更に混迷が進んでる) ふと channel はチャンネルと読んでる?チャネルと読んでる? >>473 ginのルーティングが糞なのは直ってるの? 実際goをつかいはじめのころはチャンネルの仕様とか使いかたとか調べるのが面倒で 勝手しったるmutexばっかりつかっていた gin → beego → echo → chi イマココ 言語仕様書の1.17を底本として翻訳してるんだけど、文書的に酷い(~;~の使いすぎが特に…)し、構成的にもクソだなぁ underlying type に関係した性質なんて文書全体を読まんと把握できないわ メソッド式の話では、ポインタによるレシーバーのメソッドは値による呼び出しは出来ないとか書いてあるけど、レシーバー宣言が値だろうがポインタだろうが、現行じゃ問題なく呼べるようになってる(更には値でセレクタ呼んでもポインタで呼んでも動く つまりどこかで仕様が拡張されてるのに、仕様書は更新されてないっぽい疑惑 仕様書なんて熟読しなくても、フィーリングで書いて動いちゃうから、今まで気にしたこともなかったし 気にしなくても動くんだからいいじゃない?とも思いはする そんないいかげんな感覚で思い付きどんどん拡張したその結果が今のC++のていたらくだ!! 反省しなさい! C++があんなことになったのはむしろ、C++プログラマたるもの仕様書くらい熟読しているだろうと開発陣が高を括ってきた結果だろう あんなブ厚いARMを読むなんて苦行が過ぎる 悟りに至りかねない危険な行為だ あるえー? 仕様書で終了ステートメントに続くステートメントに関する記述が無いんで、Playgroundでmainの最初にreturnを書いたらコンパイルエラーにならんかったし実行時エラーも起きない 到達不能ステートメントはチェックされないんだな そもそも規格化されてる言語じゃないし、コミュニティが用意した言語仕様書にそこまで大きな意味はないんじゃないの? 仮に処理系と内容が違っててもどっちのバグなのか第三者にはわからないこともあるだろう そうか?Googleの割にはまともだったから普及したんだと思うぞ いつものGoogleはWeb系のノリで言語作るからこんなもんじゃない、そして大コケする Rustほど初心者が書きにくくはないし PythonやRubyよりは確実に速い ちょうど良いところを付いたと思うよ だがバグらないために気を付けないといけないことが多い なんかしらんけどGoがしんどいなら使わなくてもいいんだよ バグらないために気を付けなきゃならんことなんて、他の言語に比べるとそんなに多くないだろ 言語設計でしくじってるよなぁと思うのは、構造体の生成回りの構文というか思想 Cに引っ張られ過ぎてて生成の基本が実体を作ることになってる 構造体はデフォルトでアドレスとして出現し、Javaとかのように参照と命名しとけばよかった そうすればスライスとかマップのイテレーションがクソみたいな落とし穴にならないし、マップをインデックス式でアクセスしてセレクタとしてフィールドにアクセスも出来るようにできた 実体を使いたい場合は*でデリファレンスして使う 実体ちゃんの変数も*Tという型とする 実体配列は[]*Tという配列を記述するようにする *に関しては、レシーバーとか宣言で(r *T)とかデリファレンス演算子をポインタを示す記号に使うような一貫性のなさも解消する プリミティブな変数が実体で、そのアドレスを&で取得するということからの一貫性に拘ってるんだろなぁ 実体配列なんて、Dockerの管理用配列以外で見たことないよ…少なくともレアな宣言だと思う 欠点を挙げる流れだ やっぱ入れ子の構造体の初期化でしょいかんよあれは 複合リテラルとして書けばいいんだし、落とし穴的な問題はなくない? 俺は悪くないかなと思ってるんだけど >>520 「これらの多くは、チャネルでの送信または受信の欠落、またはチャネルの閉鎖が原因です」 いや、mallocしといてfreeしてませんでしたレベルの話をされてもどうしろと? 普通に対策考えないでプログラミングなんてできないだろ >>518 ポインタを示す型なら&を使ってT &pにしてデリファレンスは*p とか実際に書いてみたら物凄い違和感に襲われてしまった …C言語の呪いって凄いわ >>522 それってプログラマー任せのノーガード戦法ってことでしょ? リストアップされてるような各種バグに対してシステマティックに検知・防止する仕組みを実装できてる? データ競合はあまり遭遇したことないな 無駄に並列化したがるバカがチームにいると地獄を見るだろうというのはわかる channel絡みのミスで固まるのはよくある >>522 けっこう終了時の後処理とか難しくない? 適当なツールとかだと雑に済ましちゃうし、割ときちんとやろうとすると書けない人多い印象。 きつい現場のGoは他の言語より殊更きつそうだというのはわかるわ channelは複雑なデータのやり取りに使うには難しすぎると感じるね どこで詰まるかわかったもんじゃないし 公式がまともなフレームワーク用意するわけでもないし いや、Goに限らない問題でGoのダメなところとか言われてもなぁ いや、けっこうGoに限った問題 channelのユースケースの大部分は現実にはpromise/futureで十分で、遥かにミスを引き起こしにくい 例えばCとかでファイルを排他オープンしたままクローズし忘れて書き込みのままになってて、別の箇所で読み込もうとしたけど開けなかったとして これはC言語の不備だとか言うのか?と >>531 chan のユースケースといったら、パイプとしてストリーム的にデータを流すのが主だと思うんだが、promise, future でどうやって代替するの? >>531 select文のあたりでも書かれてたと思うけど、同期を取る目的じゃなくてパイプからの機能だよチャネル >>531 同期取るなら、sync.WaitGroup 使えばよくない? >>532 そういうことにならないようにGoのdeferやC#のusingやPythonのwithみたいな仕組みを言語機能として提供してるよね? それらが不要だとでも? いや普通に同期を取る使い方もできるだろw 完了通知を待つ使い方 俺もその使い方しかしてない async/awaitなんで構文として追加しても良いと思うのだけどね channelは非同期機構を実装するパーツとしては優秀だから フレームワークが欲しい そもそも本当にパイプとしてストリーム的にデータを流す必要のあるケースなんて稀 Goがchannel推しだから利用者もそれに引き摺られてストリームっぽい設計になりがちなだけで、結果として単一の値(又は配列)を返せれば殆どのケースでは十分 本当にストリームが必要ならJavaScriptのasync generatorのような設計も可能で、producerとconsumerが協調するからchannelより遥かに安全だ そもそもストリームモデルが必要なユースケースってほぼ 分散環境だと思うんだよな 分散環境なら外部のメッセージバスに投げるだけだよね せっかく小さいgoroutineを気軽にポコポコ起こせるデザインなのに、 結果を受け取る方法が、データ競合を起こさないように最大限注意して共有変数を使うか、パラダイムのミスマッチなchannelを使うかなのは片手落ちに感じる 単純にgoroutineの返り値をwaitできるようにしない理由ってあるんだろうか?既に議論されてたら知りたい >パラダイムのミスマッチなchannel kwsk >>541 そりゃ>>533 の通りで、channelはストリームでありfutureではない、ってことだ。 futureで済むケースにchannelを使うと、複数の値を返す可能性はないのか?1つも結果を返さなかったら? そんな余計な心配が常に付き纏うことになる。futureなら全く無縁な心配がな。そしてその心配が現実になればプログラムは容易にデッドロックする。 >>536 だからdeferあるんだし、ちゃんとリソース管理しろよ、という Goのせいにするのはお門違いだろ、な? >>542 promise, future 程度のことをやりたきゃ、>>535 で書いたけどsync.WaitGroup使ったらどうだ? パラダイムのミスマッチという理由がわからん。 goroutineは一つの関数を呼ぶためのもんじゃないぞ。 goroutine立てて一連の処理を同期的に書くためのもなんよ。普通に考えれば結果を受け取る必要が無いはずだよ。 どうしても集めるならfan inするように一つのchanで受ける。 Futureは要らないんよ。awaitとかしなくてもそこでCPU占有したり、ioなりなんなりが起これば自動的に別goroutineに制御が渡る。 >>542 ストリームだとミスマッチでfutureだとミスマッチじゃないということか? 何と何がミスマッチなのかというところがよくわからんが。 >>544 その場合は「共有変数を注意深く使う必要がある」よね >>545 だからそう言ってるでしょ goroutineとchannelをfutureのように使おうとすればミスマッチのために煩雑でバグの生じやすいコーディングを強いられることになる もちろんGoにはGoのやり方があるのは分かるが、一方でその結果が>>520 の状況なのが事実だよね >>548 goroutineで処理すべき単位とか、ワークスティーリングの話してなかったかなと。 まさかこのスレにホーアのCSP本読んでないやついないよな?な? >>550 読もうとしたけどガチの論理学的数学で挫折 しかしよく調べたらGoが参考にしたのはその本ではなく 最初にホーアが出したもっと簡単な論文の方だった つまりその本は読む意味はない(Goの並行モデルの理解という意味で) >>547 それは認めざるを得ない Mutexと会わせ技で使ってるから >>547 だけど、120行(+テスト75行)の隠蔽ライブラリを書いて使ってる 共通変数の管理なんてその程度の共通化でカバーできるタスクじゃん Goがpromise(future)/async/awaitをサポートしてくれれば今より容易に安全に書けるケースが増えるのは事実だが、 この件も他の件と同様にGoはサポートしてくれないだろうという悲観的な現実と向き合って、 今ある手段で頑張って代替手段を安全に実現しよう。 結局ゴルーチンの実装が中途半端だったんだろうね 分散環境でのストリームモデルならNodeみたいなノンブロッキングIOで外部のソケットを叩けるようにして シングルスレッドにするのが良かったし そうでないならFuture/Promiseみたいに安全にデータを受け取れる仕組みが欲しかった この2つがちょうどうまくできないデザインになっちゃった またGoの言語仕様にも問題があった ジェネリクスだ ジェネリクスがない状態でfuture/promiseを安全に実装できない なぜかアンチジェネリクス勢がGoには多く コミュニティでの議論も進展しなかった つまり全てがゴテゴテに回ってしまった それならGoogleが並行処理のフレームワークを作ってくれるのかと期待していたが その気配は全くなく使いにくいcontextのみを放り投げた状態でさあ作れと言った状態 そりゃ普通のユーザーは付いてこれない マルチコアを効率よく使うってのがそもそもコンセプトで作られたんだがNodeみたいにしろって意味わからん Goのようにマルチコアを効率よくスケジューリングできて Goのgoroutineのように多数のタスクを身軽に簡単に起動できて Goのようにそれらタスク間でchannel通信をすることができて それらに加えてFuture / async / awaitもサポートしているプログラミング言語がありますよ 偶然ですがその言語は Goと同じくclassや継承がなく Goと同じく例外try-throw-catchもなし >>558 まずpromiseがどう有利なのか自分の口からどうぞ そこにメリットを見いだせないから無視されるんだよ Goのモデルと比較してのpromiseの優位点としてはこんなとこかな ・一般に、並行性が多少犠牲になる代わりに並行処理の複雑性を局所化する方向へとデザインが誘導される傾向がある。結果としてバグが入り込みにくい。 ・ワークフローを集約して記述しやすいため可読性保守性に優れる。 ・(channelではなく共有メモリを使う場合と比較して)処理結果を他のスレッドで利用する際にデータ競合が生じない。 ・channelと比較して、結果として単一の値を生成するというセマンティクスが型として明確に表現される。デッドロックや閉じ忘れの心配もない。 うーん今の時代にpromiseの利点を理解できない人がいるとは驚きですが仕方ない出血大サービスだ まず最初にマルチコアを活かすという点についてだが 基本的にゴールチンのような仕組みでは全く活かせないという点を強調しておく まともにマルチコアのCPUの性能を引き出せるのはSIMD命令を使った計算のみ SIMDが何なのかわからない人は調べてください SIMD演算を直接言語でサポートしていないので計算の高速化は論外 ただのマルチスレッドと変わらない マルチスレッドはOSレベルで実装されており コンテキストスイッチの負荷も高くCPUキャッシュも消えるし マルチコアを活かすような作りになってないのはご存知の通り >>562 嘘ついちゃだめ promiseでもデッドロック起きる 次にpromiseの利点について 並行処理の考え方としては大きく以下がある 1.処理をシーケンシャル実行して1つずつ結果を受け取る Aが終わったらBを実行して Bが終わったらCを実行する 2.複数の処理を同時に実行して結果をまとめて受け取る A、B、C...の処理を同時に実行してその結果をreduceして受け取る 3.ストリーミングモデル いわゆるproducer/consumerに代表されるようなモデル 1と2についてはpromiseで全て安全に楽に実装できる ゴルーチンとchannelを使った実装なんか考えたくもない 100%デッドロックが起きる 3についてはゴルーチンとchannelが本来想定してるモデルなのだが これを適切に実装するのが難しい CでBlockingQueueの実装したことがある人は分かると思うが極めてデッドロックが起きやすい 複数のproduer/consumerを生成したい場合など考えたくもない さらにこのモデルの場合は基本的に大規模な分散環境で実行することがほとんどである シングルノードでproducer/consumerなどサンプルコードでしか有り得ない こういう用途では複数ノードのソケットにリクエストを投げて結果を待つということになるので結局2に帰着される つまりpromiseがあれば全ては安全に解決される ちなみにpromiseはスレッド実装する必要はないことに注意 rustはスレッドで実装されているがNodeはノンブロッキングIOを使っている 他にもグリーンスレッドを使うなどいろいろある 言語側が安全性を担保できるように実装できるのだ そしてpromiseを型安全に実装するためにはジェネリクスは必須である 以上が私の考える 「ゴルーチンは実装が中途半端で実際のユースケースを考えた場合に非常に残念なことになっている」理由である 反論があればどうぞ そりゃpromiseでも共有メモリ触ったり外部のリソースをロックしようとしたりすればデッドロックするでしょう promiseモデルとは関係ない話 >>560 その言語はRustだな >>565 Rustならデータ競合が絶対に起こらない データ競合を起こすコードはコンパイラがエラーにできる言語仕様 >>567 ちょっと違う RustのFuture(=Promise相当)はOSスレッドとは全く別で関係なく Goroutineとほぼ同様の気軽に大量に作れる非同期タスクとして扱える もちろん安全に解決できる 今回の話で言えば大雑把に分けるとRustは3種類ともサポート ① Futureおよびそのasync/await ➁ Goと同様のchanel ③ メモリ競合を絶対に起こさない安全な共有メモリ ぐちぐち言ってきたが Goにはゴルーチンとchannelとcontextという良いプリミティブがあるのだから 適切にpromiseを実装して使えるようにして欲しいということ であれば並行処理がメインのアプリにおいては第一選択にもなり得ると思う ジェネリクスも入ったのだしやれるはずなんだよ Googleがもうやる気ないのかもしれないけど >>568 channelと比較してデッドロック起きないとか痛い事言っといてそれはないわw Nodeしかさわったことないから詳しくは知らんけどasyncawaitモデルだと async関数を使うには呼び出し元にどんどんasyncが汚染されて使いづらいイメージがあるな その点Goは同期的なコードの一部を並行処理にするってのが非常にやりやすいと思う タイムアウト処理もselectで簡単に実装できるし、シンプルなfork joinだったらsync.waitgroupで楽に実装できるし 何も困ったことがないな そんなに優位性があるとは全然思わない >>573 Goは見かけ同期と誤認するけど 同じOSスレッド上でもメインや複数のGoルーチンがスケジューリングされて交互に非同期で動いているよ 例えばGoで func1() func2() func3() と見かけ同期に書いているのは async/await対応言語で await asyncfunc1() await asyncfunc2() await asyncfunc3() と書いた時と同じ状態 つまり見かけ同期のGoの実態は非同期 「Goは最初から全てがasync汚染されているためasync汚染に気付かずに済む」が正解 >>574 goキーワードなかったら同期的に動くだろ ライブラリの中でgoキーワードが使われてるから暗黙的に使われるが正しいね。 非同期にしたい部分でgoをつけるのであってつけてないのに全部非同期だってのはおかしな話だな >>575 それは見かけ上だけ goを付けなくても読み書きなど含めて時間がかかるものは 見かけ上だけ同期ブロックしているが 実際には非同期で動いており裏で別のgoroutineにスケジューリングされている そしてその読み込みや書き込みが可能となると 見かけ上だけ同期ブロックしていたところへスケジューリングが戻る仕組みであってGoは常に非同期に動いている ユーザーに見せてるのは全てブロッキングなコードなわけじゃん それをgoキーワード使って複数立てた時に非同期で動くって話で、単体の場合はあくまでも同期的に動くよね mainルーチンでhttp.getってやったら同期的に動いてるよね? これを別のgoroutineを立てて複数立ち上げればブロックする後は勝手に非同期で動くってだけの話 async汚染はユーザー目線で言ってるね Goのモデルは既存のコードや構造に手を加えずに一部だけを非同期にするのが容易、これが一つのメリットではあると思う Node/Denoの作者も同じこと言ってるし、async/awaitモデルの方が優れている一言も言ってないな むしろGoのモデルをほめてるわ https://mappingthejourney.com/single-post/2017/08/31/episode-8-interview-with-ryan-dahl-creator-of-nodejs/ 必死にasync/awaitの方が優れてるとか言ってるみたいだけど、逆にGoのモデルの方が使いやすいって人もいるわけだよ 自分の意見が全てだと思わない方がいいんじゃないかな 感覚的な話で優れてるって言われてもね >>577 > ユーザーに見せてるのは全てブロッキングなコードなわけじゃん それは見かけだけだな 例えば>>574 の | await asyncfunc1() | await asyncfunc2() | await asyncfunc3() これも(同じく見かけだけ)全てブロッキングな同期で実行されるコード そしてGoと同様に実際には裏で非同期に動く > 単体の場合はあくまでも同期的に動くよね それは見かけだけ つまりasync/await対応言語がawait文で見かけだけ同期的に動いているように見せかけるのと完全に同じ うんだからユーザーに見せるコードが同期的なことろがわかりやすくて良いって言ってるんだけど?最初その話してたよね?同期的なコードって言ってるよ? 裏でepollやら使ってて非同期だから云々の話はしてないんで ちなみになんでいちいちID変えるの? >>576 >見かけ上だけ同期ブロックしているが >実際には非同期で動いており裏で んなこと言ったらIO操作のあるあらゆる言語が低レベルでは非同期で動いてるじゃんよ。 C10K問題から非同期が流行ったのに、メモリーを使いまわしてたら意味ないのでは? 一つのスレッドに一つのスタック、典型的に一つのスタックは1MB準備される。 10Kのスレッドがあれば、10GBのメモリーが必要。 256MBのSUNでは無理。 でも、非同期でも1MBの配列を用意してデータが届くたびに書き足していくなら同じことでは? ウェブ・サーバーが静的なファイルを送り出していた2000年ごろなら非同期が大それた力だっただろうけど。 全てが動的な現代において、非同期はめんどくさいだけなのでは? 昔より回線が安価になって接続数が多くなったんだから非同期が必要でしょ 静的なファイルを送るだけなら。 カーネルの送信バッファが空くのを待つ ↓ 送信バッファと同容量だけ非同期にファイルの読み込みを開始する ↓ ファイルデータが読み込まれると、送信を開始する ↓ 最初に戻る この手順で、典型的なTCP通信なら20KB以下のメモリーで足りる。 でも、動的なコンテンツ生成では、そうはいかないのでは? >>563 のここがよく分からない > まともにマルチコアのCPUの性能を引き出せるのはSIMD命令を使った計算のみ SIMD命令付きのシングルコアCPUもあったじゃん。 古いけど MMX Pentium とか Pentium III とか。 この時代はSIMD命令は何を引き出してたの? >>566 1なんか一つのgoroutineに上から並べるだけで良いじゃん。 えっ?もしかしてこの人 >>574 でもまだ理解してないの? >>587 httpを同期で実装するなんて昔のダメなシステムと完全ブロックしても困らない末端クライアントだけたぞ httpクライアントとして動作する時もサーバーで使うなら同期ブロックしてしまうとスレッド資源を無駄に専有 だからhttpを使うなら何らかの非同期にするのが当たり前 >>574 多くの言語でasync/awaitキーワードだらけになって反吐が出る気分だわ、これを良いと考えた人たちを殴りたい... goにpromise/futureなんて絶対不要、こんなの必要だと思ってる人相当アホやぞ >「Goは最初から全てがasync汚染されているためasync汚染に気付かずに済む」が正解 なるほど意味わからん asyncキーワードなんて無いのにスケジューリングで同期実行されるから汚染?ww新理論w >>566 1なんてそのまま関数並べるだけだし 2はN件goroutine立ち上げてたらN回チャネル待ち受ければいいだけだよね タイムアウトもselectで容易に実装できる 100%デッドロックするとか言ってるけどそれはGo超初学者が使った時の話かな? 仮にデッドロックしても検知機構働いてちゃんと落ちるし何が言いたいのか >>588 その時代のことはよく知らないので 気になって調べてみたがwikipediaによると 2クロックで実行するという実装になっていた模様 なのでその時代に関しては128ビット幅のレジスタを使えるというアドバンテージしかなかったとのこと >>591 通信プロトコルとhttpサーバー/クライアントの実装が区別できないおバカさん乙w そんなんでよくGoなんて使えるな 今回は実装の話だからサーバー上なら今どきは非同期で実装で合ってると思うよ >>593 その通りだな、安易に実装できるものを標準で欲しがる理論がわからんわ 多くの言語のfutureなんてデータの結果受信同期待ちが起こるだけだし、goのcontext.WithTimeoutは 他の言語では全く実装できていないfutureのプラス機能のようなもので、goはより進んでいると言える 一方promise的なもの、つまり複数のgoroutineを束ねて制御したい人は、欲しい人もいるかもしれないが goで書いたpipeline処理は手動で書くからこそきめ細かい制御が出来るので、無作為にこれとこれを並列、 これとこれを非同期だけど同期的に実行にしたいとか、効率を考えたらこの流れを組み替えられることには ほとんど意味もないね。 例えばJSでPromise.allとかすべてを非同期並列に実行して成功の可否で分岐したいなんて、同じ状態が goroutineとチャネル待ち受けで出来てしまうわけで、それを仰々しいライブラリにする意味が分からん 上では良いことだけ書いたけどif err != nullはもうそろそろダルいので何とか手を打ってほしいわ 副作用のある関数ではgoの第二の戻り値がerrなのは、もはや言語仕様なので別言語でいう Option/Result/Eitherみたいなものは必要ないにしても、?.のようなNull条件演算、合体演算 のようなErr条件演算が欲しい きめ細かい制御してるか? goのモデルは良くも悪くも作った水路に水を流すだけで、実際にその中のどこでどのようにブロッキングが発生するかは気にしないのが正しい使い方 どっちかというとpromise系のほうが制御は明示的だよ きめ細かいGoのpipelineって、もしかしてGoあんまり書けないのでは…? ランタイムの大勝利な事の方が多いぞ。 きめ細かいでしょう? チャネルが1個なら並列性が1つでブロッキング出来るし、並列性を持たせたいなら複数のチャネル幅を 用意すればいいだけ1段目のパイプライン処理が終わったすぐ後に、次段のパイプライン処理を普通に書く ことができるし、sync.WaitGroupを使えばパイプライン中の中間データへ同期制御もできる それ以外にGoで書かれた多くの優れたパイプライン処理は、キャンセルを考慮している。 ブロッキングが発生するかは気にしないなんて事はなく、チャネルのselectでブロッキングが入ることは普通に 当たり前だから気にしないだけ https://go.dev/blog/pipelines 世にある多くのpromiseはキャンセルやタイムアウトは考慮していない場合が多い、All or Nothingでしかない 大雑把な実行制御でしかない。多くは流れるようなデータの受け渡しもできない。 実行順を決めるだけで、特定の処理に多重度を持たせるとかそんなことは出来ない これは多くがpromiseというものが非同期処理をベースにした疑似的な実行順制御の仕組みだけであるから >>598 そもそも、複数のgoroutineを束ねて使いたいという要請でsync.WaitGroupは作られてるから、自前で作る意義すら無いんだよな グループを待つ、のだから >>593 だからその程度のことしかしないのにわざわざゴルーチンだのchannelだのselectだのを書かなきゃいけないことがだるいと言う話だよ? 書けるか書けないかで言ったらそりゃ書けるでしょw あと普通に刺さる可能性が高いと言うことを言ってる 意味わかんね >>566 では promise の利点をこう書いてた > 1と2についてはpromiseで全て安全に楽に実装できる > ゴルーチンとchannelを使った実装なんか考えたくもない > 100%デッドロックが起きる それに対して >>593 や >>598 が goroutine とチャネルで簡単に実装できるって言ったら >>605 > わざわざゴルーチンだのchannelだのselectだのを書かなきゃいけないことがだるいと言う話だよ? 「だるい」なんて話、一切してなかっただろ。 >>607 マジでアスペか? promiseの方が明らかに楽でバグが生まれない これはこれまでの議論の流れで一貫してる主張 なんでリクエストのデータ受け取るのにgoルーチンだのchannelだのselectだの書かなきゃならんのだよ そしてpromiseを実装するのは我々ではなくGoコンパイラの開発者たちだよ promiseって普通awaitするのが普通だよね? goもチャネルも使わない状態でhttp.Get呼ぶのと全く同じだよ goroutineの中で実行すれば勝手に非同期になるしfork joinしたいならチャネルがwaitgroup使うだけの簡単なお仕事 >>608 >>607 まずは「goroutine&channelだと100%デッドロックが発生してpromiseだと発生しない状況」について戦えよ。 だるいとかより興味あるわ。 >>608 「promiseの方が明らかに楽でバグが生まれない」 そんな統計は1つもないければ、あなたの貧相な頭の中だけですよね?それを証明しなさいと暗黙的に問われているのがわかりませんか? 「なんでリクエストのデータ受け取るのにgoルーチンだのchannelだのselectだの書かなきゃならんのだよ」 じゃあなんで、promiseなんていう出来の悪い非同期処理のために作り出された愚物を、真にマルチプロセスに対応するgoで エミュレーションしなきゃならないんですか?あなたのためだけですよね、ほとんど誰も欲しがっていませんけど? このような需要がない機能を、標準ライブラリに求めるものではありませんし、あなたの隠れた真の心は 「学ぶことをしたくない」だけでしょう、ご自分でも気づいてないと思いますが C#やScalaあるいはJSしか出来ないなら素直にチームに報告しましょう、あなたのやる気を引き出すためだけに我儘を際限なく 広げても誰も理解してくれませんし、当然、味方にもなってくれないでしょう。だってやる気が無いんですから。 言語の基本的な考えが違うのに、他の言語に似たような雰囲気を求めるのは間違っていますし、なおかつ結局同じコードを 書いてしまうなら乗り換えるような利点をすべて消し去るでしょう 「そしてpromiseを実装するのは我々ではなくGoコンパイラの開発者たちだよ 」 実装しないと思いますね、あなたのゆがんだ考えでは超保守的なgoチームを説得するのは無理でしょう。1つも有益な 調査結果なり、推測なりが述べられていません。あなたが「ルーチンだのchannelだのselectだの書かなくちゃならない」と 我儘を言ってるようにしか見えません。仮に万が一億が一、必要だとしてもGithubに個人実装のライブラリとしてあるでしょう まあasync/awaitのほうが初心者に対するハードルは低そうな気はする 初心者が雑にchannel使ってるとたいていバグってるわ async/await手軽で簡単だけど複雑なことやろうとすると難しい Goroutineとchannelはasync/awaitと比べると確かにとっつきにくいが複雑のことも組み合わせで上手く実現できる応用力がある >>611 そういうストローマン論法は俺には通用しないって promise の利点まとめ - goroutineとchannelを使うと100%デッドロックが起きるが promise だと安全に実装できるものがあるらしい。具体例は不明。 - >>605 にとってだるくない。 非同期で順列な処理やる場合はasyncのがわかりやすい 並列にタスクいっぱい撒いてなんかやるみたいなのはchannelって印象 promiseに似てるけど、全く違うものはerrgroup.Groupと呼ばれます。これもpromiseなんぞと比べれば コンテキストなどと組み合わせキャンセルやタイムアウト処理が容易にできますし、実行順の制御や包括した エラー処理以外にパイプラインまで簡単に拡張できます。 例1:ページをフェッチして全ての処理が終わるまで待つグループ制御(1つでもエラーならエラー処理) https://pkg.go.dev/golang.org/x/sync/errgroup#example-Group-JustErrors 例2:単純な並列タスクを同期するためのグループ制御 https://pkg.go.dev/golang.org/x/sync/errgroup#example-Group-Parallel 例3:多段ステージを設けたパイプライン処理をグループ制御 https://pkg.go.dev/golang.org/x/sync/errgroup#example-Group-Pipeline 例1、例2はJSでいうPromise.all() のような動きをしますがpromiseなんていう融通の利かない非同期のため だけの劣った機能より格段にシンプルな仕組みです。 上の例でいえば、並列タスクなどではchannelを使用せず、複数起動された軽量ルーチェンから元ルーチェンへ results配列の結果を戻していますが、これは並列タスクが一段で終わるからです。 次の(例3の)pipeline処理にあるように、並列と並列が連鎖する多段処理においてはchannelのような 仕組みを使うのがとても合理的です。もちろん、処理の終わりの同期のために、selectによる結果受信待ちは 入りますがこれはデットロックではありません もともとJSのPromiseがなぜあるかといえば、同じプロセス空間で疑似的な非同期処理による実行制御を行うため だけの仕組みです。このため、特定の変数(結果を格納する配列や変数)に同時にアクセスされるという考えは ありませんし、そのような(ロックや待ち)制御は必要ありません。現実に同時に動いていないのですから 隣国のアジア人コミュニティに「ストローマン論法」という言葉を連呼するキチガイ集団がいましたが、本当のバカだった 結局何がChannelに無くて、何がPromiseでしか解決できない問題なの? Promiseを解決せずに持ち回ること? >>617 例1がすでに全然シンプルじゃないw しかもレスポンスを返さない例で意味ないww それ以外にも落とし穴満載 現実にこんなコード書いてるやつばっかりならバグりまくってヤバそう やはり頭がバカ以前のGより脳が小さい、上の人はサンプルをシンプルだとは上でも言ってないが errgroup.Groupがシンプルだと言っているのに、頭ヤバそう まあサンプルは十分シンプルだが、レスポンスが要らない事など世の中にいっぱいある 現実にこんな奴がいることは、goより複雑な言語特性や膨大な標準ライブラリを持つ言語を チーム開発で使えるか、大変考慮すべきことだろうな まずは基本的に、シングルスレッドの場合とマルチスレッドだが共有データを使用しない場合は原理的に データ競合や排他制御のバグは発生しない。 >>611 が「promiseの方が明らかに楽でバグが生まれない」と言っているのはそのどちらかに帰着するケース。 マルチスレッドでかつ共有データを扱うケースではpromiseを使おうが競合バグは発生し得る。 ストローマン連呼する人が最近5chで増えたと思ったけどこの動画が原因なのねん youtu.be/mK3Tnxh4Kho そもそもGoは何もしなくてもマルチスレッドなんよ。 IO待ちとかしたら勝手に他の事しよるよ。awaitなんかしなくても。 だからFutureやPromiseで結果が来る事を持って回るんじゃなくて、 そもそも処理するロジック自体を複数起こしちゃうんだよ。。 これだけの事をいつまで言ってんのよ。。 >>617 の例1がどうして一気に複数リクエストを送りたいかと言うと、その三つを同じ一つの処理で使いたいからであって、 三つの同じ処理を起こすんであればWaitする必要も無いのでは? それこそchanで受け取れば良いんだし。。 JSのPromiseしか知らないんだな そりゃ話が噛み合うわけがない 内容ゼロのワイ賢者や煽りに煽りで返すスタイルwww ストローマンって本題から離れた部分を、わざと誤解して上げつらう詭弁の手法だから、自己紹介してるんだよ うぬぬぬぬ、issueに送るべきだろうか? 1、「ポインタの」レシーバーでストリンガーを記述すると、fmt.Println()とかに渡してもString()メソッドは呼んでくれない… 2、そして(str{v: 1}).String()とか記述するとコンパイルエラーになる… 変数に一旦格納してからのs.String()は、仕様から(&s).String()と解釈してくれて通る >>634 この辺(レシーバー)の仕様って、訳してみると何かガバッてるように思えてならないんだよなぁ >>634 実体のレシーバーはレシーバー内のフィールドを更新しても反映されないから、レシーバーはポインターとして書くのが定石だけど ストリンガーだけ実体のレシーバーとして書けば回避できる 回避できるなら放置でもいーじゃん?とか言われると反論しづらい >>638 ポインタのレシーバーを記述していると、インタフェース型変数には実体は代入できずポインタでなければならない という制限もイミフ 代入可能性の仕様は単に、xがインタフェースTを実装していること 実体でもメソッドセットx.String()とx.Str()は呼び出せるのだから実装されている、とは「ならない」事から上記の制限がイミフと言ってる 本当に仕様が厳密じゃなくてガバガバ 大真面目に仕様書を読み込んでる俺の純情を返せ >>639 セレクタ式で実体からポインタレシーバーを呼び出すと&xと解釈されるという仕様が、インタフェースの代入可能性には波及していない、という点でコンパイラのバグと難癖つけられるんじゃないか? とissueに書いてもいいんじゃないか?という多分にメンドクサイ系おじさんの怒り 仕様書にどう書かれていようが、インタフェースに実体を入れようとするな!で済む話ではあるかも 最終的には「仕様書は信用するな」に帰着 インターフェース型変数という訳のわからないものを導入したのがそもそもの間違いなんだよな で、なんでそんなもんを導入したかというとそもそもジェネリックスがなかったから 「ジェネリクスがなくてもプログラムは書ける(キリッ」みたいなイキりにこだわって結局かえって醜いことになるっていうまるでド素人みたいな失敗 理解できないから人格攻撃に出るあたり、お里(国)が知れるというもの いきなり国がどうとか言い出す人って日常会話出来るのか気になる インタフェース変数は普通に色々な言語にあるだろ? そこにケチをつけるのは筋が悪すぎるのではないか? >>636 1. &elem2{}で渡してるのに、func (e elem2) String() stringなんて呼び出すわけないじゃん?どういう事? 2. func (s *str) String() string で普通は定義するので、同じように呼べないからコンパイルエラー もっと言えば、s := str{}にしても (*str).String(&s)とコンパイル時に解釈されるだけで呼んでるのはポインタメソッド 下のインタフェース型変数云いいは、全く理解ができていないで我儘いってるだけで読んでる人に伝わってないし マジ何が言いたいのかサッパリ... goの仕様ほど厳格なものはないと思うけど(比べるのはC/C++や2015年代以前の言語ね、2016年以降の言語と 比べても、いまだに詳細なメモリレイアウトさえ公表できない某錆より厳格だ)本当に大真面目に読んでる? golangを始める必要性に駆られて、こんな簡単な入門初めのプログラムでケチ付けたいだけじゃ? issue書いても良いけど、保守的なgolangメンテナーに絶対相手にされないよ >>648 ちゃんとコードを読みなよ elemはポインタレシーバーで実装、elem2は実体レシーバーで実装 そしてポインタレシーバーでストリンガーを書くと、fmtパッケージとかでは認識されないケースがあるってサンプルコードよこれ つまりあなたの主張する func (e *elem)String() string という「普通の定義」では動かないケースを示している 実行してみ?俺も「普通の定義」だと思っていたからこそのレスなんだから func (e *elem) String() string と書くとストリンガーとして認識してくれないと説明して サンプルコードまで載せて確認を求めてるのに 実行すらしてもらえないとは 仕様書にポインタ変数.は勝手に*(ポインタ変数). に変換されるとか書いてあるけどインターフェースでも行われるってのはどこに書いてあるの? >>651 ない むしろ、インタフェースを実装しているという定義が、全てのメソッドセットを満足している、という程度しか書かれていない あれ?仕様書だと逆に値は (&x).xxxx に変換されるとしか書かれてなくなかったか?後で確認してみる ポインタと値レシーバーは特に注意しなくても相互にセレクタとして呼べるんで気にしていなかったんだけど、ポインタでストリンガーを書いたらfmtパッケージの関数では認識してくれなかった んで、これは不味いと総当たりで確認してみた しかし、単に自分の勘違いかなと確認コードを公開してみて、レビューを求めている←イマココ まだfmtパッケージの中は見ていないけど、ポインタレシーバーで書くと型スイッチかリフレクションではインタフェースを満たしていないと見なされたりするんじゃないか?とか不安になってきた 上でも書いたけどfunc (e *elem)String()は自分も「普通の」書き方だと思ってたんで な、仕様なんてこいつ読んでないだろ?5chぐらいでしか自分の連投でしか意見言えない issueとかこいつは言ってみただけでそれすら出来ない >>655 そいつ次世代言語スレで機能精神崩壊してたんだぜ 自分のRustの実力(知ったか)で仕事にありつくのが難しいと観念して これからはGoに粘着するよ ここが新しい 隔離スレ よろしく頼む 理解できない ・ポインタでストリンガーを書いてしまうと動かないケースがある ・実例をプレイグラウンドで上げたから間違っていたなら指摘してくれ に対しての回答になってない これこそ関係のない些事を上げ連ねて議論を避けるストローマン話法の典型じゃね? Promise最強ストローマンおじさんw 仕様書なんて読んでないんだろ?そもそも英語読めないから読んでないどころか読めないんでしょ?w なんか勘違いしてるけど相互運用ではないよ レシーバが値のメソッドはポインタと値に対して呼び出すことができるが ポインタのメソッドはポインタに対してのみ呼び出すことができる これは仕様書に書いてある >>659 これで全部解決しててワロタ 二度と喚き散らすなよ >>659 んにゃ 「メソッド呼び出しと同様に、アドレス指定可能な値を用いたポインタレシーバーによる非インタフェースメソッドへの参照は、自動的にその値のアドレスを取りますのでt.Mpは(&t).Mpと等価になります」Method values より とあるよ >>659 As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of the value; t.Mp is equivalent to (&t).Mp. のトコね 誤訳してるなら指摘してくれな まあ、こんな感じにぜーんぶ読み通さないと系統だった仕様の把握ができそうにない、という点で、かなり品質は良くないんよ これ、どっちが優先されるの???という話が多すぎて、実際に試行するとアレ?となる 仕様書の全訳に挑んでオカシイとサンプルコード書いて確認してみてレスしてるのに 仕様書を読んでない奴がそのサンプルコードをRunすらせずに、お前が勘違いしている、とか へそで茶わかしていいでしょうか? >>662 いや、それ暗黙的にポインタに変換してるからポインタに対して呼び出してるよね? 理解できてる? >>664 なんだ英語読むのに苦労してる人か そういう人が日本語訳に取り組むと迷惑 オカシイところがあると言うなら原文の方にPR出せ はいサンプルね interfaceはポインタレシーバーだとポインタ変数しか代入できないのに対して メソッド呼び出しは全部成功しているよね? https://go.dev/play/p/X71811pJ1sQ メソッド呼び出しとインタフェースの仕様を混同しているから話にならない 英語読めない文盲ってことが証明されたな >>667 わかってないふりしてるけどもう理解できたんだろ? インターフェースのマッチ時のメソッド呼び出しについては>>659 明示的に呼び出す場合は>>662 で変換される (自分で呼び出すのだから当然インターフェース云々とは無関係) でもGoの知識増えたしいいんじゃない? 育成は成功だ Googleのたかが1プロジェクトが C++で始まるからと言ってGoの終わりを感じ始めるなんてどういう審美眼で生きてんだよ。 >>673 そうなんだろうけど、言いっぷりがなんかちょっと引っかからんか お前やる気ないんか?ってメンションしたいくらいだわしないけど(´・ω・`) >>674 普通にリプで使われまくってるって言ってるが Googleってコーディングに関しては無茶苦茶保守的というか統制的だからな 開発者の好みより合理的判断を優先した結果だろう そういう文化だからこそGoみたいな極右言語が生まれたとも言えるのだが 数多の捨てられたプロジェクトに比べればGo言語は成功した部類だろうよ。 なんでC++なんて使ってるんだよ 新プロジェクトで使う言語じゃねーだろ Googleは独自のビルドシステムなど過剰に最適化された開発環境を持ってるから、簡単に言語変えられないんだよ いや、たんに仕事が雑なだけだとおもう とりあえず新プロジェクトやるぞー! で?言語は? C++で。 あれ?ウチの会社なんか新しいのはGOでやるとかいってなかったけ? そうだっけ?べつにいーじゃん、Goはマスコットきもいし、C++のほうが楽だから俺んとこはこれでヨロシク! こんな感じだろう RustじゃなくてC++なのが逆張りっぽくてキモい Dが2001年、F#が2005年、Goが2009年(年はwikipediaに書いてあった登場時期) うまく並びそうだなと思たんだけどEがない Goの次はHack(2014年)で間違いないよね。 最小とか最大を求める関数は自分で作れって話なの? あと、整数の絶対値とか 二分探索できたりする場合もあるからそういうライブラリはあえて作ってないんだと思われる ライブラリ側で最適な実装で作れる場合はちゃんと用意されてることが多い (http2とかDB周りとか) windows環境でGoをアップデートするにはどうしたらいいでしょうか? 新しいバーションで上書きインストールしちゃえばいいんでしょうか? Chocolateyでやってるのを見てみると、上書きっぽいけど GoなんかどうせWinネイティブで使う意味ないんだから、WSLでHomebrewでも使って入れたらいいんじゃない ちなみにChatGPTはセッション的に一連の会話を一時的に覚えててくれるらしいから、 二回目には同じ関数のコメントが省略されてる 関数の名前を明示すれば、「○○のテストコード書いて」でやってくれたかも まあスレチだな >>703 テストケース考えるときの助けによさそうだな たいしたもんだ Go言語はこの先生きのこれるのか?聞いてみたら面白いかもな。 やはりChatGPTだめだな! "かわいらしい外観が特徴で愛される存在となってる" こんな回答では人類の知性にまだまだおよばない! ただしい知性ある回答はこうだ! "きもかわいい外観で一部のマニアックなgo開発者に愛されています" 地元のマイナーなサッカーチームについて聞いたら「日本でも見逃すことのできないチームの一つ」とか適当に答えたぞコイツ IT系以外は知ったかする >>710 ITでも知ったかするよ N88BASIC書いてもらったら大嘘な奴が出てきた ちゃんと下げ親指ボタン押して運営にレポートするとよろし 真面目な話、わからんことを素直に「それについてはわかりません」と言ってくれないのはかなりタチがわるいな 新入社員だったら要注意人物だよ >>712 わかりません と答える場合もある AI君がわかった気になってるだけ 更にタチが悪いけどもw スレに沿って書くなら、エンジニアの仕事はまだまだ安泰だが、使いようによっちゃ楽はできる って感じね rainu/go-command-chain: A go library for easy configure and run command chains. Such like pipelining in unix shells. https://github.com/rainu/go-command-chain CLIの引数の読み取りするライブラリーは何がおすすめ? kingpinは最近更新されてないからkong試してみたが なんか使いづらい ここに挙がってる他のやつ試そうかと思う https://www.reddit.com/r/golang/comments/9uybnt/choosing_a_library_for_cli_application/ Neither, personally I like https://github.com/jessevdk/go-flags. I like the declarative approach a lot more than the imperative one used for many other options, and it's extremely feature-rich. >>717 Cobraはこんな感じのこと書かれてるけど どんなコードを指してるのか分からん kingpinは直感的に使える気がするけどメンテナンスされてない 問題なければこのまま使えば良いか? Both cobra and urfave/cli both enforce a globals-heavy, inversion-of-control architectural pattern that's difficult to maintain. IMO, Kingpin is the only widely-used CLI library that takes an appropriate architectural approach. >>718 読んできて判断すればいいじゃん。そんなに読めないものじゃないし使い方も難しくない。アーキテクチャはたしかに理想的ではないと俺も思ってるけど、利用面からの意見としては、、 実戦で使用されていて信頼できる 機能面でも多言語の相当品と同じことがまあまあの書きやすさで書ける。ただしやや歴史的機能があったりして隅々まで洗練されてるとは言い難い印象 コマンドラインの補完などほかの言語では少々保守が面倒な機能があって便利 っと思ってる。でもとにかく評判より自分で確かめたらいいよ cobraはサブコマンドを無限に生やすような大規模向け、Kubernetes/dockerで使用されてる。 そこまで拡張する予定がない場合はgo-flagsかもっとシンプルな mitchellh/cliかな?ちょっとオプションがあるだけなら標準?のflagsだろうけど、普通に*nixのfindぐらいオプションがあるならやっぱりgo-flagsがおすすめだわ 大した関連性がないのに1つのバイナリのサブコマンドになってるより、別プログラムのほうが設計もメンテも楽だしcobraが**とても**メンテしやすいという話だけど、それは変らない。 本当にそこまで多数のオプションで動きが変わるようなプログラムを作るのか?という自問自答が必要だと思う、いやcobraは良いと思うけどね ジェネリックスって、有名どころのOSSのライブラリで活用されたりしてるの? それとも手遅れ? ORMあたりでこねぇかな Go言語でマイクロサービスの実装を解説してる書籍はありますかねえ? >>724 以下は、Golangを使用してマイクロサービスを開発するための書籍です。 "Goで学ぶマイクロサービス設計入門" - 田中 充史 著 この本は、Golangを使用してマイクロサービスを設計する方法を解説しています。サンプルコードを使用して、マイクロサービスの作成、展開、スケーリングなどを実践的に学ぶことができます。 "GoによるWebアプリケーション開発" - 佐藤 幸一 著 この本は、Golangを使用してWebアプリケーションを開発する方法を解説しています。マイクロサービスの設計と開発に必要な概念と技術を学ぶことができます。 "Goマイクロサービスパターン" - マテウス・カルステンス 著 この本は、Golangを使用してマイクロサービスを実装するためのパターンを紹介しています。パターンに従って実装することで、マイクロサービスの堅牢性、柔軟性、スケーラビリティを高めることができます。 以上の書籍は、Golangを使用してマイクロサービスを開発する際に役立つ情報が含まれています。どの書籍も、実践的なアプローチを採用しており、Golangの基礎から応用まで幅広くカバーしています。 Go言語入りユニクロTシャツ、Akamaiが提供 コードを動かしてみた人も=ITmedia 今期の公式調査が来たからみんな答えよう 以前の発表通りエラー制御に本腰入れ始めるのかまたもや意識調査が含まれてた AIについての質問もあったし標準で組み込まれる未来もあるのかしら Goはこの中途半端な立ち位置のまま この限られた用途以外で一般的に使われる言語にはならないと思われる 昔Rubyがブイブイいわせていた時、私はPythonを選びました 本物には本物が分かります、そして私は静的言語としてGoを選択します そうです、これが本物の回答なのです いえ、これは私が優れているということではありません Goが優れているということなのです goもこのまま衰退してしまうのだろうか。 今からならrust覚えた方がいいかな。 そういえばジェネリクスはもう実装されたんだよな。もうinterface{}地獄じゃないのかな。 まだ地獄やろ、 そんなはやくライブラリに取りこまれないんじゃないか ORMとかどうなったのかな かなり早い段階で翻訳が出たな 原著公式レポがあるから動かす手間を惜しまなければ何がダメなのか分かるけどね https://github.com/teivah/100-go-mistakes/blob/master/09-concurrency-practice/68-string-formatting/main.go “開発の失敗学”から生産性とコード品質を高める。『Go言語 100Tips ありがちなミスを把握し、実装を最適化する』 Goプログラミングの間違いを網羅的に解説した一冊 https://forest.watch.impress.co.jp/docs/bookwatch/news/1524131.html https://www. アmazon.com/100-Mistakes-How-Avoid-Them/dp/1617299596 翻訳者ご本人 柴田芳樹 5.0 out of 5 stars The equivalent of "Effective Java" >However, please note that there are many minor errors in the book, so if you can read Japanese, I recommend the Japanese version that I have translated. なおreadme翻訳募集中 README: Japanese translation 🇯🇵 https://github.com/teivah/100-go-mistakes/issues/30 最近goはじめたけど、例外処理になれないわ 今まで安易にスローしてきたつけが出てる感じ 女性がイクときは3パターンある 1.come(欧米) 2.go(日本) 3.end(日本ではあまり知られていない) mattnさんのGo本半額だったのに買い忘れた… 昨日でセール終わってた goいいよな わかりやすい でもpythonのあほみたいな量のライブラリ使った後は自分で作んなきゃいけないんかとなる マイクロサービス向けの言語だから APIサーバーとか小さな特化したものを サクッと作るのに適してる それ以上のことやると死ぬだけ まさしく適材適所 勉強がてらGoでwebサービスやってるけどLaravelで良いじゃんって気がしてしょうがないw PHP Laravel再評価の時代来そう > PHP Laravel再評価の時代来そう こない。 プロの労働市場は、Ruby, AWS Solution Architect だけ。 Java は多重請負構造のIT 土方 米国年収でも、Rubyは、Go/Rust/Elixir の3大言語を超えた! Ruby, Elixir : 9.3 万ドル Go : 8.9 Rust : 8.7 多くの言語 : 6.5〜7 PHP : 5 Dart : 4.4 PHP, Dart は、コンピューターサイエンスを勉強していない高卒用言語 フレームワークは、 Ruby on Rails : 9 万ドル Django : 6 Laravel : 3.8 YouTube で有名な雑食系エンジニア・KENTA が言ってる。 初心者のキャリアパスは、Rails → Go のみ Ruby/Goの神・HashiCorp のMitchell Hashimoto がそう。 Ruby製のVagrant → Go製のTerraform。 今は、Goプログラマーしか求めていない PHP, Scala はKENTAがオワコン認定したので、絶対にやってはいけない言語です! 米国年収でも、Rubyは、Go/Rust/Elixir の3大言語を超えた! 2022 -> 2023 Ruby : 9.3 -> 9.9 万ドル Elixir : 9.3 -> 9.6 Go : 8.9 -> 9.3 Rust : 8.7 -> 8.7 多くの言語 : 6.5〜7 -> 7.3〜7.8 PHP : 5 -> 5.9 Dart : 4.4 -> 5.6 >>753 GoogleはGoにしたいのか、Rustにしたいのか >>759 確かに現状用途が異なる。GoがWeb、Rustがシステム記述 しかし、本来はGoもRustと同じところを狙っていたのではないかと goとrustじゃあ全然言語機能違いすぎるよ goは言語自体くそシンプルでだからバックエンドのマイクロサービスみたいな 小さなサービス自体を実装するのに使われてる(用途) goでそれ以上のことをやると死にかけると思う GoとRustはC#とJavaみたいなにたもんじゃないと思う 逆にRustでバックエンドのWebサービス実装する フレームワークあるけどコンパイル時間長すぎて Webとか時間の流れ速い分野ではこれはこれで地獄だし GoとRustは色々比較して別物だからな 用途も現状すみわけられてると思う 本来についてはどうなんだろうね Goはシステム記述を最初から狙ってたの? システム記述がどこを指すのかにもよるけど でも実際GoogleはGoで書かれたものもRustに移行してる 生産性は同程度だけど不具合の数が圧倒的に少なくなったらしくかなり前向きっぽい RustはC/C++の代替言語なわけで結局メモリ管理のための記述が必要な低級言語なんだよ〜 ガベージコレクションの無い低級言語なんか触りたくないぽよぉ〜、Goしか勝たん! シンプルな言語機能でコードの保守性を高めることがGo言語の目的で、それはRustと真逆のような Rustが人気な理由は 完全にメモリ自動解放しかも必ず安全 を実現しつつC言語と同等の速さで動く点 つかメモリ管理が~とか中級者まででしょ 普通の頭があれば25歳までに卒業してるわ javaがウケたのもcがウケたのも シンプルだったからなんやろねえ 実際のプログラミングってのはどうしたってクソみたいな 状態の山、依存の山みたいなもんに取り組んでいくわけで 余計な複雑さを持ち込まないでほしいってのは現場のリアルな声だと思う もちろんgoも、それをわかってて、それを押さえてる >>769 Cが受けたのは他が糞だったから。勿論Cの完成度は超高いにしても。 あとその当時はCPUが非力すぎて軽くないと話にならなかった。 Javaが受けたのはCで鬼門だったポインタを廃止してGCも導入し、馬鹿でもバグが出にくくなったから。 その後スクリプト言語が受けてるのは富豪プログラミングの方が断然楽だから。 ただ効率を考えたらポインタを直接扱える方が断然有利なので、Goは簡単な範囲でポインタを使える言語の位置づけだと思う。 ただしJavaは敷居を下げすぎて業界にバカが多数流入した ポインタを取り扱える/扱えない がハードルとして機能していた Go関係ない話ですまん >>762 初老のおっさんのyoutubeで見たけど actix-web使ったプロジェクトのビルドに10分位掛かってた。 もうちょっと頭使って環境作ればいいのに ちなワシの環境なら10秒程度 こんばんは Goってネームバリューあるけどそんなに盛り上がってる感じじゃないよね javaの後継になるかと思ってたけどそうでもないし 言語仕様が簡素な点が特徴だけど Javaのような大規模開発には向いてないかな ガベージコレクションがあるからC/C++の分野も不向き 守備範囲が意外に狭い >>774 Javaが大規模開発に向いてるのは「文化」であって、「言語機能」ではないだろ Goで技術的に出来ない事はない。ただしやる意味もないが Goが糞なのは「全部書け」という言語ポリシーだが、これはJavaも同じだし >>773 Javaの代わりにGo使うメリットってポインタが使える事くらいか? ならJavaの連中はポインタが使えない(使わなくて済む)からJavaに行ったのだから、 > javaの後継になるか これ自体が間違いだな ただまあ、GC付きCの需要は以前からあったし、この分野ではそこそこ生き残り続けるのでは? javaの代わりにGo使うメリットってネイティブコード吐き出すことだと思うけど 処理速度が早くなればそれだけマシンのリソースが少なくて済む >>777 ああその点は完全に失念してた。 ただなんつーか、今時鯖代より人件費の方が高いので、Web鯖なんて物理で殴る方が安いというソリューションになってしまってる。 Javaも同様の状況だと思う。 Webに比べて製品寿命は長いので、状況異なるかもしれんが。 処理速度が絶対的に必要なのは物理で殴って逃げられないケースで、 これは例えばディスコードやFPS等のゲーム、つまりユーザー間でのデータのやりとりが大量にある状況で収容数を増やしたい場合で、 現在はRust/C++ということになっている。この分野でJavaを選択する奴は居ない。 Javaが使われてるのは大概インフラ、つまり銀行の送金システムや自治体の戸籍管理等だが、 負荷がかかって物理で殴って逃げられないのはDBであってJava記述部分ではないので、 最大でも精々2倍程度にしか速くならない現状で、Goに書き直す事はない。 それよりも書き直す際のバグを嫌うはず。 つまり、Rustが存在せず、鯖代が今の10倍くらい高ければ、JavaをGoに書き直す需要は発生してたはずだが、そうではなかった、ということ。 > Javaの連中はポインタが使えない(使わなくて済む)からJavaに行ったのだから、 アマチュアさんからはそう見えるんだね 職業マにとって言語なんて案件次第なんよ >>779 速度面も機能面も、GoはJavaの後継ではない >>780 ゆとり乙 顧客次第というのなら、現時点でのJava案件は今後ともJava案件だろうよ 顧客は公務員かお堅いところで、「もし何かあったら誰が責任を取る?」しか考えない連中だから C++しかなかった時代ならともなく、現時点でJavaを「安全」とする技術的意味はないが、 顧客はそれを理解出来ず、また、責任逃れの為に誰も先陣を切らない ただオラクルが妙な動きを見せ始めてるから、その辺どうなるかだが、それでも公務員連中は金払って終わりだろうよ 所詮は税金であって、自分の金ではないから そういえば三菱銀行は10-15年前にC++で書きました、Haskell使いました、とかやってたが、続報は聞かないね >>782 ゆとり引きニート乙 >>773 一応捕捉しておくと、773がGoを「速いJava」と『個人的に』考えたのは間違いではない。 ただし『言語として』なら完全に間違いだ。 Javaはビルジョイが「Cでのバグの大半はポインタがらみで、ポインタ使用ケースの9割がStringだった。 だからStringを言語がサポートすればポインタをなくせると考えたんだ」とリーナスに語ったとおり、 ポインタを無くしてバグを減らす為の言語として作られてる。 そして実際、大受けして天下を取った。(なお「大半」と「9割」は逆だったかも) ただ、速度チューンにはポインタでの効率化が必須で、この意味でGoは「速いJava」として『個人レベルでは』使える。 ただしJavaにはそもそもポインタがないのだから、 この発想、つまり「ポインタを使えば速くなる」とはJava使いは考えないし、実際、出来ない。 (個人レベルなら出来るのは混ざってるだろうが、Java流の開発方針だとチーム全員が出来ないと意味がなく、機能しない。 そしてポインタにまつわる問題をデタラメに吹聴してる震源はJava使いであって、具体的に言えば「メモリリークガー」だが、 C使いがメモリリークに悩まされる事はない。それはCの使い方を知らない馬鹿がデタラメやってて勝手にバグってるだけ。 この意味で ID:vlvoJs2w は正しい事を言ってる。なお俺は ID:Chhm4gg1) そのようにC/C++を自分は使いこなせると思い込んでいる多くの人たちによってセキュリティホールが生み出し続けられている 結局C/C++を使用禁止にするしか解決策はない アメリカでは政府レベルで決断して声明を出したので日本も後を追うだろう 「ソフトウェアはメモリ安全でなければならない」との声明を発表、米ホワイトハウス:「C」「C++」よりも「Rust」などの言語を推奨 https://atmarkit.itmedia.co.jp/ait/articles/2403/18/news045.html AIによるコンパイラによってC/C++は復活する、コンパイル時にメモリ安全がAIによって保障されるのだ さらにAIコンパイラがはくエラー&提案によって誰もがC/C++マスターとなる つまりRustの人間にメモリ安全を強制する構文ルールは瞬く間に錆ついてしまうのさw もちろんAIの恩恵はガベージコレクションにも及びGo、Pythonなどの実行速度も劇的に上がる つまりRustはすぐに錆びついてしまうのさw AIという母なる海によってね >>785 そう思う人がC/C++を使わなければ済むだけ。 > そのようにC/C++を自分は使いこなせると思い込んでいる多くの人たちによって なお、これはただのコンプレックスで、 ポインタの概念を理解すら出来ない馬鹿はお引き取り下さいではあるが、 ポインタを理解できたがリークするのは、やり方を知らないだけ。 (そしてここはGoスレであり原則後者だから、前者は死ねでいい) ただ問題は、Javaの連中が「メモリリークガー」とデタラメに吹聴してるのに騙され、 文法にて縛ってしまうRustに逃げてしまってる事。まあ初心者は文法しか見えないから致し方ないが、 実は定番の手法があり、踏襲すれば絶対にリークしないだけ。 賢いからリークしないわけではなく、知ってるか知らないか、守るか守らないか、でしかない。 そしてRustは実際はC->C++->Rustと来ないと意味もメリットも理解出来ず、 「RustのおかげでCを入門する奴が増え、現在RustよりCの入門者の方が多いじゃねえか!」とか2019頃に言われてた気が。 RustはCを駆逐したいようだが、間抜けな話だ。 そして、Javaが「安全」とされていたのは、 ・ポインタにまつわる問題が無い ・配列の境界チェックあり (←これGoはどうだったっけ?忘れた) ・GCありなのでリークしない ・サンドボックス だと思ったから、技術的に見れば確かにGoはJava+ポインタ=高速版Javaとしての側面はあるのだろうよ。 ただ、マーケティング的に(781)、また技術者リソース的に(784)、当面は無いが。 この意味では俺はRustの方が詰んでると思うよ。AIで出来るとは思って無いが、(>>786 ) ・動的な境界チェックをやってる限り、Cの速度に勝てない ・静的な境界チェックが出来るようになれば、C++にも導入されるだけ で、出口が無い。 そして意味もなくマウントを取って来た780が言う様に、現在のJavaプログラマはポインタを扱えるのなら、 Java->Goへの大移動は起きるのかもしれんよ。この意味ではRustよりGoの方がワンチャンある。 (けどまあ、普段やってないことがいきなり出来るわけも無く、ゆとり引きニートの言い分なんてお察し、だが) そんな心配しなくてもAIが進化すればGOもC/C++もRustもなくなって別の高級言語が生まれるよ、もう会話してればプログラムができちゃうような感じになる >>788 配列の境界チェックは任意に与えられたインデックス値に対してはC言語であろうとなかろうと境界チェック必須 一方で配列の内部であると確認されているなら不要(にすることができる) 例えば配列の内部であると確認されているならその配列内部へのポインタとして持ってしまえば 読み書きアクセスのたびに境界チェックは不要となる よく使われる配列の全体もしくは一部分の範囲を順にシーケンシャルアクセスする場合もポインタにすれば境界チェックを不要にできる なぜならその範囲の終端条件に達するまでは内部であると確認されてるため個別の境界チェックは不要 RustがC/C++と同じ速さで動くのもこの原理のため >>792 言ってる事は知ってるが、そうではなく、 > 任意に与えられたインデックス値に対して の時に実際どうしてるか聞いてる。 C言語の場合は、境界チェックして無い。 Rustの場合はするらしい。だからこの部分でどうしてもCより遅くなる。 Javaは勿論やってる。だから馬鹿が書いて添字範囲をオーバーしたら、例外が返されたはず。 Goはどうだったっけ?という事。 で、Javaが792の手法でゴリゴリに高速化し、C比3倍遅かったのが1.8倍程度まで盛り返したのも知ってる。 そしてC#の方はJavaが6,7で留まってた際にも言語自体が進化してたので、高速化がまだJava程には至ってない。 あと、ついでに言うと、(別人かもしれんが) > セキュリティホールが生み出し続けられている > 結局C/C++を使用禁止にするしか解決策はない これも間違いで、C/C++の場合は788に書いたとおり、 ・(プログラマの技量により)バグを生みやすい ・ベアメタルなので問題があった場合に直撃する だが、アプリとしてはバグが無い(上記上側がクリアされてる)、という前提なら、RustはC/C++と比べて安全ではなく、同程度でしかない。 セキュリティホールは設計上のバグだから、言語関係なく発生する。 (だからLinuxをRustで書きなおそうという馬鹿は居ないし、居てもポシャる。 そういえば10-15年程前はLinuxをC++で書き直そう、という連中が居たはずだが、消息聞かないところを見ると、完全にポシャったようだし) ただ、Javaの場合はセキュリティホールを突いてもVMだから、さらにVMのセキュリティホールを突く必要があり、この意味では安全。 Goの場合はランタイムだから、VM程ではないにしても、ベアメタルよりはまし。ランタイムの実装によっては、VMと同等の堅牢さも確保できる。 ただ、言っちゃ悪いが、Rustの連中がやたら布教に熱心なのは、所詮はその程度の言語なんだと思うよ。 JavaScriptなんて悪口しか聞かないが、蔓延る一方だろ。プログラマに支持されてる言語はこうなるという例だよ。 Rustは精々ポリコレがんばってください。俺はRustは死ぬと予想してるし、そう望んでます。 >>793 配列の境界チェックをしなければどんな言語でも範囲外アクセスで続行となり致命的な穴となります だからC/C++以外はどんな言語でも境界チェックが行われています C/C++でも自分で境界チェックを行わなければ致命的な穴となります したがってそこで速度差は生じません なんかスレが進んどる。半分は読んでない。 けど大規模開発になると些細なパフォーマンスは関係なくなることには同意した。 それを差し引いても自分はGoが好き。 >>794 Cで境界チェックしてる奴なんて、世界中でも誰もいない。 境界オーバーは純粋にバグであり、プログラマの責任でデバッグしておけ、というのがCの文化。 そしてずっとそうやって来てる。 だから動的に境界チェックをしてる限り、RustはCよりも原理的に遅く、実際そう。 この意味ではRustは補助輪付きCであり、補助輪の分だけ遅い。 Rust=馬鹿向けC、といえば分かりやすいか。 そして、C/C++でなんら問題なかった連中からすると、 Rust?記述がウザくなるがリークがなくなって境界チェックしてくれる? いやリークなんて元々しないし、デバッグもちゃんとやってるから間に合ってるよ、であり、 何もメリットが無いからRustなんて使わない。 とはいえ数は力である。 Cの場合は「リークや境界オーバーするような馬鹿がコード書くな」であり、 コードを募る場合は中~上級者だけに対象を絞る大前提だが、 Rustの場合は「文法に従ってさえすればリークは防げます、境界オーバーは動的チェックしてます」らしいので、 大多数の馬鹿からもコードを募れる。これが今の時代には向いているのも確か。 ただ、馬鹿向けCなら、Goの方が上だと思うよ。境界チェックしてたかは忘れたけど。 >>798 Goももちろん正しく配列境界チェックをしていてindex out of rangeのランタイムエラーが出るよ Cだけが基本的なこともできない古い失格言語で範囲外をアクセスしてしまう >>799 なら馬鹿向けCはやはりGoで決まりだな。 そして、「僕は馬鹿だから補助輪ください」か、 「俺はちゃんとデバッグするから補助輪なんてイラネエ、100%の速さをくれ」か選べる。 それでいいのでは。 (というかこの辺グダってるのはRustだけで、Go使う連中は最初から100%の速度なんて求めてない。 Rustが原理的にCより遅いのは回避しようも無い事実なのに、嘘ぶいてるからおかしなことになる。 そしてこの手のことを「選択肢を絞り、政治的に解決する」のがパヨクの常套手段で、典型的には>>785 パヨってるRustは当然嫌われてるだけ) ただまあ、もう一度整理すると、Goは ・ポインタにまつわる問題はそれなりに対策されてる ・配列の境界チェックあり ・GCあり ・ランタイム だから、経緯とか界隈の文化とか技術者の状況を無視して、単に純粋に言語の技術的側面だけを見ると、Goは > javaの後継 (>>773 ) は言えてるのかもしれんね。 そういえばJavaは「元祖馬鹿向けC」、Goは「2代目馬鹿向けC」と言われてたし、自然な発想なのかも。 ただ「安全」に関しては、一度保険をかけたら二度と戻れないものだから、Javaの連中がGoを「安全」と見なす事はなかなか無いとも思うが。 (ランタイムエラーを吐いてくれる環境で動いているソフトは、 ランタイムエラーで誤魔化せてるから動いているのか、 そもそもバグが無いからランタイムエラーは絶対にないのか、区別付かない。 だから、ランタイムエラーがある環境でどれだけ動かした実績があっても、『保険』をはずしてベアメタルに持って行くことは出来ない) Cと違ってGoは賢い str := "01234" a := []byte(str) fmt.Println(a[3]) // → 51 (3のascii code) fmt.Println(a[3:5]) // → [51 52] (3と4のascii code) fmt.Println(a[3:7]) // → [51 52 0 0] (範囲外の値は0になる) fmt.Println(a[3:9]) // → panic: runtime error: slice bounds out of range [:9] with capacity 8 >>801 > fmt.Println(a[3:7]) // → [51 52 0 0] (範囲外の値は0になる) これはランタイムエラーのほうがいいのでは? >>804 動作の一貫性が無いから。 或いは fmt.Println(a[3:9]) を [51 52 0 0 0 0 ] (範囲外の値は0になる) でもいいが、べき論ならランタイムエラーに揃えるべき。 境界オーバーはプログラマ起因の単なるバグであり、修正することを期待されるので。 ランタイムエラーは本来 ・メモリ不足 ・DB開こうと思ったが応答が無い、或いは何らかの理由でDBに書き込みが出来ない ・ユーザー文字列をevalしようとしたが、エラーになる 等の、『プログラマのミスではない』問題に遭遇する可能性がある局面でtry-catchするものであって、 プログラマ起因のバグがあってもそれなりに動かす為の仕組みではない。 けどまあ、実際はお前のように後者だと勘違いしてる奴が多いのも事実。 だからJavaは基本的に低品質、というかCでは許されない品質のコードが大量に混入することになる。 これをもって「安全」とするのは本来は間違ってる。 (低品質のコードでもそれなりに動かせる環境自体は研究する価値があるのも事実だが、これは本来は明確に別件としてやるべき。 なおGoの場合はpanicから復旧する手段はなかったような気がするので、この点は多少ましかも) read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる