Go language part 2

■ このスレッドは過去ログ倉庫に格納されています
1
垢版 |
2017/11/11(土) 19:25:26.19ID:X8lWnCzG
Goについて扱うスレッドです。
GoはGoogleによって開発された言語です。

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

日本語訳
http://golang.jp

※前スレ
Go language part 1
http://mevius.5ch.net/test/read.cgi/tech/1381374291/
2
垢版 |
2017/11/11(土) 19:49:11.79ID:X8lWnCzG
書き込み待って読んでから8時まで待つべきだったかな。
不要なら立て直してね。
一応言い訳すると、スレタイも変わったしそっから長いから普通に二スレ目だと思っとったわ。

もっかい書いとくと、APIが不足してることはない。

995 あ sage 2017/11/11(土) 19:23:54.10 ID:X8lWnCzG
まあ、要らないカラムが多すぎるだけなら、
row,err:=sql.Queryで、
column,err:=row.Columns()
vals:=Make([]sql.RawBytes,len(column))
args:=Make([]interface,len(column))
for i:= range values {
 args[i]=&vals[i]
}

でvalsとargsつくって、
Scanに(args...)で渡せば、
使うときにvals[i]をstring(vals[i])とかよしなにしちゃえるんじゃないの?
2017/11/11(土) 19:52:22.20ID:proXGFSN
>>1
乙。だがhttp://golang.jp/って推奨されないurlじゃなかったっけ?
4
垢版 |
2017/11/11(土) 19:54:54.11ID:X8lWnCzG
>>3
最早死んでるんだっけ?
申し訳ない。単純に引用した。
今どこか良い日本語のサイトがあれば、書いてもらえるとありがたい。
5
垢版 |
2017/11/11(土) 19:57:12.37ID:X8lWnCzG
>>2
あ、これrangeでvals受ける所をvalues受けてる。あとからargsが4文字だからvaluesもvalsにしよう、とか文字数とか調整してはいかんかったな。
2017/11/11(土) 23:47:05.71ID:LLMRc4SD
(前スレ)>>984
> 同意する。Goでデータベース操作の決定版がでないのが物語ってる。
>
> 逆にGAE/goのdatastoreを使うときはGoとの相性の良さを感じる。
> スキーマがGo側に設定することが決まっているから。

再度調べて、また考えて、大体理解した。
RDBはKVSと比較されるからKeyValueではないと勘違いしていたが、実はKeyValueそのものだ。
一方、静的言語は基本的にValueだけの世界で、Keyはコンパイル時に落ちてしまい、リフレクションするしかない。
ここが絶望的に相性が悪い。これはGoの問題ではなく、静的言語一般の問題だ。
だったらもうORMにしてしまえ、ということで、GAE/Goのdatastoreは見る限りそれに近い(と思う)

というか、静的言語でDB操作の決定版って、ORMじゃないと無理だろ。
自前のリフレクションはかなり死ねるし、そこを隠蔽してくれないと意味がない。
ただ、ORMまで持ち出すのなら「速度の為に」わざわざ静的言語を選ぶ理由がなくなってしまう。
DBで律速するのなら、動的言語でも大して変わらないはずだし、
管理も楽なら、もう動的言語で組んでしまえ、ってことになる。
(型の問題を回避する為にmapを使っても、同様に速度優位性のない無駄なシステムに成り下がってしまう)

意識したことはなかったが、静的言語では「型」を通じてプログラム全体がゆるく密結合してる。
これは「自分のみ」の世界では全く問題ないのだが、
JSON/RDB等「KeyValue前提の他人」と組み合わせる時にはかなり最悪だ。
PHPが糞言語なのは事実として、何だかんだで他を圧倒して生き残っているのには当然理由があり、
この相性問題はかなり大きい。
また、PHPerやJavaScripterが馬鹿にされる割には何とかなってるのにもこれが寄与してる気がする。
Java鹿が「オブジェクト指向で粗結合化(キリッ」してるのは割とミクロな粗結合化で、実はあまり意味がない。
今回のようにReadとWriteを丸ごと粗結合化することは静的言語(の優位性を保ったまま)では基本的に出来ない。
動的言語では速度は最初から捨ててて、組みやすさだけを取っており、割り切り感がいい。

この点、Goは若干中途半端なポジションだが、
Go = C+GC+型システム+リフレクションかな?
C++がリフレクションしたらかなり被るね。
7
垢版 |
2017/11/12(日) 00:34:07.92ID:nCH5w166
リフレクションせんでも、アサーションで十分じゃないの?
プリミティブ以外が入ってる事もほぼ無いだろうし、
型無しのinterfaceから、特定のinterfaceへアサーションした方が幸せになれるだろ。
Stringerであれば良いとか。
8
垢版 |
2017/11/12(日) 00:42:26.80ID:nCH5w166
まずORMって何か考えれば良いと思うが、Object Relational Mappingだ。
リレーショナルデータベースに入れないのであれば、ORMじゃない。
ORMを、単にデータベースにオブジェクトを入れる道具の代名詞にしてるが、全然違う。

DatastoreはRDBではない。
CouchやMongoみたいなオブジェクトを放り込めるDB。そういう部分には向いてなくはない。
9
垢版 |
2017/11/12(日) 00:53:31.35ID:nCH5w166
JsonとRDBを同様にキーバリューと考えてるみたいだが、「RDBは同じ列で構成された行の集合」、Jsonは「「キーで表された値の集合」の集合」であって、キーと列はかなり違う。なぜかと言うと、Jsonは「キーで表された値の集合」単体で成立するが、
「値の集合」は列がないと存在できないし、全ての値の列は同じである必要がある。
だから、マッピングせなならん。
別に、RDBでもID,シーケンス,区分列,値列で持ってメタテーブルみたいにしても良いんだから。

そこがテキトーなのは、単に作り方が雑なだけ。

ちなみに、タグに書いとけば、コンパイル時に抜け落ちる事はないので、それこそreflectで取れる。
2017/11/12(日) 02:15:58.04ID:EpH8iSoP
GoでRDB使う時に本当にきついのはSELECTとかLEFTJOINとか駆使して
カラムの構造がquery毎に違う可能性があるからなんだよね。
結局クエリごとに構造体作るしかない。
つまるところGoとRDBの組み合わせは避けるのがベスト。かも。

queryの結果から構造体をコード生成する方法があると良いんだけど
2017/11/12(日) 02:48:56.74ID:miP6tQAF
てか、staticメソッド無しかよ!これどうなのよ?
ファクトリ作りたいんだが、まさか外に転がせと?ひどくね?
とりあえずクラスメソッドをインスタンスnilで呼んでみたがアウトだし。

なんかもう、色々酷い。
この言語は多分、ベタにしか書けないし、それをよしとする言語だ。
Cだと思えばそんなものだとも思えるが、これは逆に言うと、
Cしかやってないか、Cで何も問題を感じない奴が使う言語だね。
確かにこれだとC並みの速度は出るだろうが、これでは開発効率もC並みでしかない。
新しい言語と言うよりは、新しいBetterCの提案、と考えるべきなのか?

というか、これまで20年ほどでだいぶ積み上げたソフトウェア産業の資産、
「ソースコードはどう書けば見やすい/将来に渡ってメンテ出来るか」
をここまでガン無視していいのか?とも思える。潔いと言えば潔いが、どうなのよこれ?
若干意識高い系共によって肥大化した感のあるソフトウェア方法論へのアンチテーゼかよ?
ミニマリズムというか。

最近は一周回ってCを知らない馬鹿も偉そうにしているわけだが、
そいつらにとってはGoは新鮮なのかな?最近の言語とはだいぶ違うから。
ただ、GoはほぼCだぞいろんな意味で。
2017/11/12(日) 03:04:41.10ID:miP6tQAF
>>10
> queryの結果から構造体をコード生成する方法があると良いんだけど
evalだね。Goには当然ないが。

C#でLINQでevalモドキを作っていたのがあったはずだが、
(心はC++のExpressionTemplateみたいなノリで、
演算子と評価順をデータとして記録しとけば、式程度ならデータ側だけで出来る、というもの)
それと同じノリで上手くいけるか、だね。
フィールドのオフセットさえ決まればそれは構造体なわけで。
ただ一般的にはオフセットはコードに静的に埋め込まれているから、
回避するにはオブジェクト指向の仮想関数テーブル(vtbl)みたいな仕組みが必要になる。
逆に言えば、これさえあれば動的な構造体を簡単に扱えるようになる。

JavaScriptは無駄に速くなっているが、この手の仕組み持っているんじゃないかな?
V8はプロトタイプ毎に型扱いでnewしてるようだし。(正式名称があったが忘れた)
13
垢版 |
2017/11/12(日) 08:19:16.13ID:nCH5w166
>>11
自分の型をポインタで書いたらnilで呼べるだろ。

可変長もそうだし、ちゃんと言語仕様読め
14
垢版 |
2017/11/12(日) 08:21:19.77ID:nCH5w166
なんで既存コードが読めないんだろう。
セルフホストされるようになってから長いぞ。
2017/11/12(日) 10:25:55.87ID:fotpQfC1
>>11
goにクラスの概念はないぞ、ドキュメント読んで勉強し直せ
2017/11/12(日) 10:28:45.53ID:miP6tQAF
>>13
お、ポインタレシーバならnilで受けられるのか?
しかしまあ、ベタで書くことにした。
というか、どうもその手の「ちょっと綺麗に書くテクニック」を全力で否定するノリのようだし。

なまじ隠蔽出来るから無駄に肥大化するのであって、管理が厳しくなったらパッケージを分けろ、なんだろ、多分。
まあ分からなくもない。
JavaScriptの関数スコープは最初は戸惑ったが、結局のところ関数を小分けにすればいいだけであって、
Cとかはなまじブロックスコープなんてあるから無駄にでかい関数になってしまうのも事実だ。
Nodeのコーディングルールなんて段々短くなってて、どうも今は「関数は10行にしろ」と言っているようだし。
(以前は19行だったと思った。今ググったら15行(多分更新されてないだけ)ってのはあった)
同様に、基本的にパッケージ内にベタで転がしておき、無理ならパッケージを分割、というのも妥当な方法ではある。
そもそもメソッドも(見た目は)ベタで転がってる訳だし。

まあこれはいいとしても、generic的な物がもうちょっとないと、昔の定義のコピペプログラムが必要になってしまう。
この点については何で端折ったのかよく分からんなあ。
C++のテンプレートは暴走気味だし、そういうのを嫌ったのかな?
まあいずれにしても、俺にとってはGoはbetterCとして理解した方がいいというのはかなりはっきりしてきた。
2017/11/12(日) 10:39:35.54ID:q/8e/fjb
もう「味見」は終わった様だし、やっぱり go は使わなくてもいいんじゃないかな
2017/11/12(日) 11:07:28.87ID:miP6tQAF
>>17
いやまだ終わってないんだなこれがw
道草食いまくってるからだが。

ただ、GoはWebには不向きというか、新規機能追加等で変更を迫られた場合、
PHP/JavaScript等と比べて3-5倍のコード変更が必要になりそうだ。
そしてこの、変更時のコード量がCと比べてほぼ同量だ。だから開発効率はかなり悪い。
パッケージが揃っているからとっつきやすいだけで、
(ライブラリを熟知している)バリバリのC++使いにとっては魅力はほぼ無いだろう。
とはいえ、「とっつきやすいC」という存在価値があるのかもしれない。
というか、C++は取っつきにくすぎる。あれは完全に暴走してる。Linusが毛嫌いしているのも分かる。

とはいえ、Goでプロトタイピングするのは辛いのは分かった。
というか、はっきり言ってろくな言語がないなこれについては。
JavaScriptは非同期のおかげでかつてのgoto文プログラムみたいな構造になってしまうし、
PHPは言語仕様が糞過ぎて思わぬところでバグって引っかかりまくるし。
RubyもPythonも前方宣言必須のゴミ言語だし。
同期JavaScript(マルチスレッドだよ!)が出れば一人勝ちじゃないのかな、と思うが、
あいつらの非同期はもはや宗教だし。
2017/11/12(日) 11:10:17.27ID:mnpiucg8
長文だらけで追い切れんけど

愚、言語がヘボでカラム分からんとDB操作が出来ません
賢、いやいや、アサーションでこう書けば出来るじゃん?
愚、他言語だとこんなので出来るんだけど
賢、じゃ好きなので書けよ、どうぞどうぞ

まとめるとこんな感じ?
20
垢版 |
2017/11/12(日) 12:03:16.36ID:2U0xoSHY
>>16
ちょっときれいに書くテクニック、が他の言語と違うだけだよ。可変長引数に参照のスライスを渡す、とか、
取り敢えず受けて.(type)でswitchしてcaseに型書いて処理するとか。

ジェネリックに関しては、あれば良いなと思う事もあるが、実際やってみたらrangeで事足りたり、
chanにとにかく突っ込んで、空selectとcase xxx<-xxxchでさらに事足りたりと、便利な読み方はある。
システムコールのselectで複数のファイルハンドル待つ感じ。

>>18
多分ウェブに関して言えば、ちゃんとしてればPHPの工数の4番の1くらいになると思うよ。
ちなみに、JavaScriptでマルチスレッドマルチコアは、クライアントならWebWorkerやら、nodeなサーバならclusterとか色々ある。
21
垢版 |
2017/11/12(日) 12:10:41.95ID:2U0xoSHY
そもそも、クエリの結果イコール構造体にならない事の方が多いでしょ。
構造体の入れたいフィールド(と読み捨てるカラムを放り込む値)の参照を持ったinterfaceのスライス投げるのが一番手早い。
入れたいフィールドのカラムを集めてinterfaceのスライスを返す関数用意しときゃ済むじゃん、ゼロクリアは保証されてるんだから。
2017/11/12(日) 12:18:47.91ID:EpH8iSoP
>>21
ちょっとわかりづらいからサンプルコードある?
23デフォルトの名無しさん
垢版 |
2017/11/12(日) 13:50:03.49ID:EHhowjYE
構造体を自動生成するとして中身のわからん構造体をどうやって使うんだ?
24デフォルトの名無しさん
垢版 |
2017/11/12(日) 13:57:51.09ID:EHhowjYE
結局リスレクション使った遅いもんになるだけでしょ
過度の抽象化は害しかないって偉い人が言ってた
25
垢版 |
2017/11/12(日) 14:26:56.37ID:dH1+f21j
>>22
>>2
hogeって構造体があって、そのxxを取りたいなら、
のargsの、欲しいカラムの場所に&hoge.xを入れるだけ。
構造体を自動精製するんじゃなくて。

リフレクションとアサーションは違うし、そもそもそこまで遅くないぞ。
2017/11/12(日) 15:10:02.64ID:miP6tQAF
つーか、これ、構造体のメンバ名を都合3回書く必要があるじゃねーかよ!
度を超したクソッぷりにビビる。つーか、お前らマゾなのか?

1回目:type struct 内 ← うーん、まあ静的言語なら仕方ないか
2回目:rows.Scan 内 ← 速度の為なら仕方ないか、、、
3回目:メンバ名は大文字で始めてjsonタグをいちいち書け ← 死ね

PHPやJavaScriptでは1回も書かなくていいんだぜ!
さすがにこれには切れたよマジで。
https://qiita.com/vvakame/items/6719b3c90dfaa8220e44
2017/11/12(日) 15:14:41.46ID:mnpiucg8
>PHPやJavaScript

どうぞどうぞ
28
垢版 |
2017/11/12(日) 15:22:14.00ID:dH1+f21j
>>26
Scanには書かんで良いだろ。何読んでんだよ。

Jsonなら、*interface{}で受けて、map[string]interfaceで値とりゃフィールド名出てくんの一回だろ
だから、>>9で、RDBのように行と列が分離してねえんだよって言ってんじゃん。

しかし2chで知りたいことがあればdisれというのはホントだな。
29
垢版 |
2017/11/12(日) 15:25:33.81ID:NnV+WxW3
これで、Cをやってたからついてける、お前はGCの動くタイミングが、とよく言えるな。
Scanの実装見て喋ってんのかなぁ。
30
垢版 |
2017/11/12(日) 15:31:37.75ID:dH1+f21j
dynamicとかnewtonsoft.JsonのJObjectで受けないC#でもクラスのフィールドに属性つけなきゃならんし、こいつが何を問題にしてるかわからん。
cやcppで書いたらライブラリ使ってももっと地獄じゃん。

動的言語しかやった事無いから辛いと言ってるだけに見える。
2017/11/12(日) 18:57:59.72ID:miP6tQAF
前スレ>>977

まさか3回も書かされるとは思っていなかったから今更ながらxoを試した。
が、これもちょっと冗長だな。
標準で go generate がついている時点で、公式も糞っぷりを認めてる。
ASTとか完全に屋上屋を架してる。
ろくな解がない。

構造体メンバを1回書くところまでは許すとして、
Scanは構造体を受けろ、JSONはlowerCamelスイッチをつけろ、ってとこだね。
2017/11/12(日) 19:10:52.14ID:q/8e/fjb
(最初に戻って) sqlx 使えば良いんじゃない
33
垢版 |
2017/11/12(日) 19:12:41.31ID:I2Yxw4dL
新参を足蹴にするような真似はしたくないが、
3回も書いたのは自分だろ…。
34
垢版 |
2017/11/12(日) 19:18:34.25ID:I2Yxw4dL
可変長引数を受ける関数には、...でスライスを渡せる。
構造体渡したら構造体の(カラム名と同じ(!))メンバに入れてくれる事を望んでるんだろうが、
型がハマらなかったらとか、そもそもクエリでasで別名つけてるかもとか、キャストしたけどasで同名つけてる、とか、クエリ側が勝手な事するリスクを全部解決して構造体に入れる手段を考えてから考えれば良いのに。
まぁmap[string]interfaceが落としどころじゃねえの?フワフワ適当なクエリ投げたいなら。

クエリ自体もGoに書かせたいなら、最早SQLと繋げる意味なかろうて。
2017/11/12(日) 19:29:15.19ID:q/8e/fjb
>>31
> Scanは構造体を受けろ、JSONはlowerCamelスイッチをつけろ、ってとこだね。

ま、↓にでも投げてみたら

ExperienceReports
https://github.com/golang/go/wiki/ExperienceReports
2017/11/12(日) 19:30:43.54ID:miP6tQAF
>>32
構造体で受けるだけならそうだね。
ただ、毎回リフレクションはかなり厳しいから、うまくキャッシュしてくれるかどうか。
refrectを見る限りシグニチャは発行してくれないっぽいし。
ポインタ演算を禁止しているから、CみたいにOffsetofの結果を配列でキャッシュできないのも残念な所だね。
使うときは速度/ソース確認必要といったところか。

今回は速度の味見だし、とりあえずベタで書いた。
ただ2回書きまでは覚悟してたが、3回とはね、、、
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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