Rust part9
レス数が1000を超えています。これ以上書き込みはできません。
Rustを学びたい人はまず最初に公式のThe Bookを読むこと
https://doc.rust-lang.org/book/ 最近は初学者向けの文書も充実してきてるね
Tour of Rust
https://tourofrust.com
Rust explained using easy English
https://github.com/Dhghomon/easy_rust web_sys使って意図的にHTML食わせてDOM操作とかしたいんだけどこれって出来ない?
https://docs.rs/web-sys/0.3.44/web_sys/ >>7
rustからDOM叩くのはバインディングさえ用意すれば出来るけど"意図的にHTML食わせて"の意味がわからん。 >>8
HTMLのテキストをDocument::from(&html_text)みたいに読ませて、そこからDOM操作してDOMのvalueとかattrとか読みたい。
他のHTMLパーサーは規格がバラバラだからweb_sys使いたい >>10
それkuchikiをそのまま使うのに比べてどういうメリットがあるの?
css selectorで指定できたほうが簡単で柔軟だと思うんだけど
>>9
HTMLパーサーの有名どころは、scraper, select, kuchikiの3つだけど
どれも内部的にservoのhtml5everを使ってるから一緒じゃない? easy-scraperは個人的に仕様がダサいと思う
>>11
web_sysのドキュメント見たら分かるけど、APIがかなり豊富でMDN遵守してるし、wasmにも移管できる。
その三つは楽だけどそれ以外はweb_sysの方が良いから >>12
wasmにも移管できるって、web-sysはwasm前提だと思うんだけどwasm以外で使えるの? >>12
ダサいといえばダサいんだが、綺麗さより楽さを取ったデザインって感じの話が作者のブログに書いてあったよ。 >>9
whatwg DOMにDOM Level3 Load & Saveがないから今のDOMで外部ファイルのパースはできない。
適当なAPIでファイル読んでwasmにコンパイルした他のDOM Level3実装に食わせればいい。
rustで書かれたDOM Level3実装が見当たらないから他言語になるかな。
whatwgのDOMはesからhtml操作する以外は考えてないから、そういう事したいなら他でやるしかないね。 綺麗に作れないから自分が楽な設計をしたというだけ
アラフォープログラマにありがちな言い訳 >>16
「楽な」は「楽に使える」という意味だぞ。
綺麗な設計を捨てる方が作るのは大変に決まっとろうが……。 >>13
ごめん、そこらへん認識甘いかも
wasmのランタイムじゃなくて、普通にrustcでも動くんじゃない?
>>15
そうなんだ、貴重な情報ありがとう。 easy-scraperのブログみて試しにkuchikiでやってみたけどドキュメントがなさすぎてkichikuだった
次はscraperにする the bookの分かりやすい更新履歴みたいのってある?
1度読み終わって以降に新しく追加された章や節がないかを確認したいんだけど
githubのcommitログ眺めていく以外の現実的な方法が見つからなくて困ってる >>22
cons cellにしてからflatするの面倒くさい。
俺はvec::Drainをas_sliceする用途がよくわからん。ただの変換用だろうか。
こっちの互換性残ってよかった。
ttps://github.com/rust-lang/rust/pull/74150/ anyhowとthiserror 初めて知ったわ
std::Errorが便利になるまではこれ使っとけばよさそうだね とっくにfailureのフィードバック終わってるけど、ver古くない? 結局今は何使うべきなの?
std::Error? failure? anyhow? @rustlangって日本語のRTもするのか
機械翻訳で読んだのかな いつになったらベンチマークStableにすんだよな ベアメタル用のコードを-C opt-level=0でコンパイルして乗算のオーバーフローチェック等のpanic機構って使用できる?
アセンブラリストを出力すると存在しないラベルの分岐命令が出力されるんだが正常な動作なのか・・・ 例えばこんな感じ
ttps://uploader.purinka.work/src/17641.png
callqの行き先が不明 >>28
failureは役目を終えた。std::error::Error,thiserror,anyhowでfailure相当になる。
最近はenumxのcexで静的例外風にかけるけど。
>>31-33
panic_handlerを書いた覚えがないなら自分で書く。stdにはデフォルトの実装が用意されてる。
The Embedded Rust Bookに詳しく書いてあるから、rustupでローカルにダウンロードしてrustup docで開ける。
emitだとコンパイルまでしかしない。依存先すらコンパイルしてなかったと思う。 サンキュ
>>33
ビンゴだった。でも欲しいのはアセンブルリストなのでlibcoreを含むリストをどう入手するかが課題です
objdumpだと元のソースコードの行数等のデバッグ情報が失われるみたいだしグローバルの有無等の取得方法も判らないし
そもそもgasフォーマットじゃないから見方が判らないところがあるし
>>34
panic_handlerを自分で書きたいのはヤマヤマですが記述例が見つからず棚上げ状態です
ttps://rust-embedded.github.io/book/start/panicking.html
は見ていますが記述例は見あたりませんし ターミナル上で色つけるのとテキストポジションを決めたいだけの簡単なTUIアプリ作りたいんだけど、有名なTUIクレートが多くて迷ってます。
適切なクレートが何か分かる方教えてください。 複雑なことしないなら termion
なんてどう? >>35
英語読めないって話?
>A behavior can be chosen by declaring a #[panic_handler] function. This function must appear exactly once in the dependency graph of a program, and must have the following signature: fn(&PanicInfo) -> !, where PanicInfo is a struct containing information about the location of the panic.
>Given that embedded systems range from user facing to safety critical (cannot crash) there's no one size fits all panicking behavior but there are plenty of commonly used behaviors. These common behaviors have been packaged into crates that define the #[panic_handler] function. Some examples include: MirakurunクローンのmirakcってRustでかかれてるのか
ソースちょっとのぞいてみたけどサッパリだった >>42
そうじゃなくて
>Given that embedded systems range from user facing to safety critical (cannot crash) there's no one size fits all panicking behavior
の意味がわからないんだろう。ベアメタルで人の書いたpanic handlerの中身なんて読んでも意味ないし。 >>42
それだと基本的に>>32と大差なく見えるというかリンク後に逆アセンブラリストを追いかけたら
最終的にfn panicへ制御が渡っている事を確認しています
>>34でpanic_handler書いていないみたいな事が書かれていたので別の書き方があるのかと・・ お前らの考えとしてぶっちゃけどうよ?
今後10年でc/c++を凌駕する存在になり得るのかRustは 10年もありゃRustベースのもっといいやつが出てきそう C++ 30よりは普及するんじゃないか。
(30とかどんな魔境になってるんだろうか…) 折角Edition分けしてんだし、一部後方互換性をバッサリ捨てて冗長な表現を纏めて++回避したら流行りそう
なおロードマップ見渡してもその予定は一切御座いません(笑) Rustって未だにセルフホストできていない事に驚いた
標準添付のライブラリのビルドを試みたら
>error[E0554]: `#![feature]` may not be used on the stable release channel
等が大量に吐かれたw 要nightlyかよ >>52
それをセルフホストできてないというかどうかは知らんがビルドしたいならx.py使えよ。
bootstrapにはそれ用のオプションがちゃんとある。 rustc: 1.48.0-nightly (130359cb0 2020-09-01)
src: 1.46.0
でもダメだった
>>53
丸ごとビルドしたい訳じゃなくて一部だけビルドしたい
ttps://qiita.com/kotetuco/items/54af67d5663013ad0db7#rust-core-library%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B
こんな感じ。実際にはコンパイルオプションを調整したいけど
コンパイルできる組み合わせを探すしかないのか?stableとnightlyじゃコードツリーのディレクトリ構造からして違う有様だしなぁ >>55
thx。それを実行するにあたって最低限必要な物ってなんだろ。書いていないような・・・
Pythonとbetaなコンパイラが必要そうっぽい事は判るけど
というかコンパイラも含めたビルドは出来るだけ避けたい
環境(Windows)やマシン(2Core/8GB)のリソース的に成功するか判らないし失敗した場合の
トラブルシュートも難しい
あとそのコマンドはnightly?beta?限定のような。1.46.0 stableのコードツリーだとディレクトリ名が違う >>51
ほんそれ。
ある程度はシュガライズすべき >>56
環境構築はREADMEだな。
https://github.com/rust-lang/rust#building-on-windows
ディレクトリはちょうど運悪く先月くらいに構成変わってて、今betaまで反映されてるから次のリリースでstableも同じになる。
とりあえず今のstableなら以下でcoreだけビルドできるはず。
./x.py build --stage 0 src/libcore
コンパイラはx.pyが適切なバージョンを勝手に取ってくるから任せればよい。 2Core/8GBでLLVMビルドするのかなりつらそう forとiterの使い分けってどうしたらいいんだろ
用途? codewarsをRustで解いてるけどなかなか勉強になる 敗戦国に対する差別を助長するとアメリカで主張していこうな! Cargo.tomlにrustのバージョン指定する方法ってどうやるっけ?
どこかで見た気がするんだけどcargo reference探してもないから知ってる人いる? >>65
Cargoにその機能はないな。rustupの機能として
rust-toolchainファイルにバージョンとかnightlyとか書けるよ。
当然rustupを使っていないと効果はないけど。 低レイヤーのアルゴリズム実装てrustは実は向いてないんだよ。 なんでIteratorの方にはchunksとかwindowsとかないの?
Vecに変換するのめんどくさい stdにない理由はしらんけどItertoolsでできるっしょ rustのormって何でdieselしかないの?dieselが完成されてるから?それともrustがdb使う用途に使われることが少ないとか? rustに関わらずormって限らられたシーンでしか使えない印象 >>70
任意のimpl Iteratorからスライス作るためにはcollectしてVecを作るなど、比較的重めの処理が必要になる
コストのかかる処理は明示的にやらせるというのがstdのポリシーなので、用意されていないのでは
あと利用者側で .collect::<Vec<_>>() を追加するだけでよくて対処が難しくないのもわざわざstdに追加しようとする人が現れない理由だと思う >>74
コストのかかる処理は ってIteratorにないからコストかかってるのでその理由は成り立たない気がする
個人的にはIteratorとスライスという違う型に同じメソッド名が生えてるのがあれなのかなと思った >>72
Dieselが早いうちに作られて支配的に使われるようになって他の連携クレートもdiesel用を用意してそして誰もいなくなった的な展開
個人的にはdieselは癖強いから完成度高くないと思う、ただ連携はかなり強い >>75
allocation不要なchunks/windowsの実装ってどうやるの?
Iterator ではなくて std::vec::IntoIter などに実装するということ? itertoolsの実装どんなんかしらんけど、
itertoolsのchunksは各チャンクがイテレータになってるし、
windowsのほうはtupleで帰ってくるからアロケーションしないんじゃね? すまん、チャンク・ウィンドウの個数分のアロケーションはさすがに発生してると思うわ多分 VS2019の拡張機能にRustがあるんだけど、これは本物ですか?
VSCodeのとは違うみたいで情報がない &'static strってデータかテキスト領域どっちに入るの?デバッグ方法分からん Rustってむずくないですか
これ最初にプログラムやる言語じゃないよね…昔にC触ったとかそんなレベルだと全然わからん std::collections とかが複数形でstd::markerが単数形な理由ってなに? >>85
この言語は、深いことをやろうとするとメンドクサイだけではなく、
ちゃんと仕様が公開されて無い事が多いから難しくなる。 >>87
公開されていないというより確定していないことは結構ある。
細かいところでは処理系の実装の現実に頼らないとしゃーないってのは
C/C++ でもなんでも同じだし、
まあそんなもんです。 何の仕様が知りたくて見つけられなかったのか言ってくれよ チュートリアル追ってみたらLinkedListの実装に結局
unsafeなことやらなきゃいけないみたいに書いてあって
やる気なくしたアホくさ LinkedListはもうオワコン
あれはCPUが遅くてキャッシュミスとかあまり考えなくても良かった時代のもの 初心者が「まずは独自コンテナクラスでも実装してみるか」っていって討ち死にしていくのはしばしば見られるよな。
Rustのコンテナ実装は高難度なので素直に標準ライブラリを使いましょう、ってどこかに書いてあるべきかも。 >>97
大抵の人にとってhello worldの次にやる課題としては高難度過ぎると思うけど。
もちろんおまえにとっては簡単で面倒なだけってのは別に否定しないが。 別にRustのチュートリアルはプログラミング初心者のためにあるわけじゃないし >>93
一番問題なのは、ヒープに対する参照の詳細が英語でもどこを探してもないこと。
Box<T>, Rc<T>, RefCell<T>
などの詳細と、生存期間、所有、借用、コンストラクト時のMoveの処理の話。
Option<T>はまだ分かるが。 >>95
それは信頼できる情報か。
キャッシュミスし易いから、LinkedListは、もう動的配列より絶対的に劣る、
などというようなことを書いたまともな論文でもどこかにあるのか。 Cアルゴリズム入門的な本があるように
Rustアルゴリズム入門的な記事があっていい気がする 任意の場所への挿入・削除とかは動的配列よりLinkedListでやったほうが効率いいし >>94
unsafe使わなくてもできるよ
stdのLinkedListがunsafe使ってるのはパフォーマンスのため
独自実装のLinkedListなんでプロダクションでは使わないだろう
unsafe使わないやり方で作ってみればいいと思うよ >>101
まともな論文ではないけどC++のハゲがそんなこと言ってなかったっけ キャッシュミスしやすいのはそうだろう
メモリが連続してないんだから当然だね
ただ時代遅れってのは勝手に付け足したろ >>100
「ヒープに対する参照の詳細」って何じゃい?
Box<T>, Rc<T>, RefCell<T>は標準ライブラリだからライブラリのリファレンスを見る
>生存期間、所有、借用、コンストラクト時のMoveの処理の話。
こっちは一般原則だから普通に明記されてると思うけど
Language Reference本も完成はしてないから書いてない詳細もあるだろうけど
それで困るのは一般原則的なことじゃないでしょ C++ のコンテナは、デフォルトでベクター
ゲームプログラミングでは、プログラマー自身がまとめてメモリを確保する、
メモリ管理システムの例が、よく載っているけど、
一般用途では、ベクターの速度には勝てないのじゃないか?
2分木とか、特殊用途なら別だが
Elixir でも、リストは先頭・末尾だけが速いだけで、
中間の要素を取得するには、N / 2 要素をたどる必要がある
ただ、Elixirは関数型で、元の要素が変化しないから、
更新時だけ、要素をコピーすればよい C++のvectorでも深い考え無しに闇雲に使うと
要素コピー発生しまくりなアホなコードになる LinkedListと動的配列の違いは速度だけの問題じゃないんだな、これが。
前者はプログラミング上、後者より圧倒的に有利な場面がある。
それは、要素の識別性だ。 C++のRAIIイディオム、SharedPointer、Moveセマンティクス
でRustにメモリ安全でどこまで対抗可能かな C++は確かに道具は十分揃ってるんだけど、
適切に使えるかどうかはプログラマーの注意力次第なので厳しい…。 LinkedListが役に立たないと知ったのは結構前だな
Javaのスレで色々議論があったんだけど
LinkedListが優位になるであろう場面でもArrayListのほうが早いと断言するやつが居て
バカじゃねーの?と思いつつも実装してみたら完全にArrayListのほうが早かった
古い知識でイキってた当時の自分が恥ずかしい > C++は確かに道具は十分揃ってるんだけど、
> 適切に使えるかどうかはプログラマーの注意力次第なので厳しい…。
そもそもC++は注意力の前に必要知識が多すぎる
>>114
ベンチのソースとか記事ないの? 適当に検索した記事みてみたら普通に予想通りの内容だったけど リンクリストのキャッシュミスが問題になるのであれば
探索時にプリフェッチしておけばよくね?
今時の高性能なプロセッサなら大抵そういう命令を装備しているだろ
遅いのは実装がウンコなだけなんじゃ リストの要素がそれぞれ離れたアドレスにあるような実装だったら、クソデカキャッシュ必要になったりしない? 最近のDDR4(?)メモリの速度の進化も凄いから、キャッシュミスがあっても、
キャッシュがヒットした場合の3倍位の速度低下で済むんじゃないかと思うし、
少なくとも、キャッシュミスによる速度低下には上限がある。
一方、LinkedList、動的配列の途中への挿入や、途中要素の削除にかかる時間は、
全体の要素数を N とした時、それぞれ、O(1)、O(N)となる。
キャッシュミスによる速度低下が高々3倍程度なのに対し、
動的配列の遅さは、要素数 N に比例してしまうから上限がない。
だから、本質的に要素数が多くなった場合には、
キャッシュミスによる速度低下とは比べ物にならないくらい
速度差は歴然たるものとなる。 >>120
[補足]
動的配列で途中への挿入や途中要素の削除では、平均で、 N/2 要素程度のコピー動作が
入る。これを >>121
これをMoveに置き換えて高速になるのは、要素の中身が、Heap領域など、要素自体
とは別の場所に有る場合である。たとえば、
struct Element {
const char *m_pszText; // new char[]で確保したHeap領域を指す0終端文字列
};
簡単のためこれの固定長配列を書いてみれば:
Element g_arr[1024];
となる。この要素のデータを読み取る場合は次のようになる、
for ( int i=0; i<1024; i++) {
printf( "i=%d, text=%s\n", i, g_arr[i].m_pszText );
}
この場合、m_pszTextは、ヒープ領域にとってあるから、結局、配列でも
キャッシュミスは生じ得る。
ということで、動的配列でMove動作が有効である例では、たとえ動的配列で
あっても、結局、キャッシュミスは生じる。 ここまでベンチなんもないのでとりあえず適当に拾ったやつ
https://dzone.com/articles/performance-of-array-vs-linked-list-on-modern-comp
総データ量がキャッシュをはるかに超えるとかだと多分変わってくるんだとは思う
その場合でもUnrolled linked listとかを使うのがいいってことにはなるのかな? >>123
大体そういう人は、リンクリストの本質を理解できてないので、
「先頭から10番目の場所に挿入する」
などという馬鹿な書き方をしている。
例え博士課程とかの人でもそういう馬鹿な人がいる。 >>124
C++のSTLは設計は馬鹿なので、先頭から k 番目に挿入するなど言う
馬鹿な統一関数がある。
それは、リンクリストにとって最悪の挿入法で、O(N)の時間が掛かる。
だから遅い。
数学的なイマジネーションが無いので、その間違いに気づかない。 >>125
いくら測定しても、理屈が間違っていれば、間違った実験結果となる。 >>125
グラフだけ書いて、ソースがない。
どうせ、k 番目に挿入すると言う馬鹿コードになっている。
いくら言っても、同じ間違いをする人が続出する。 数学が出来ない人は、生まれつき脳が馬鹿なので、
この人も、乱数で番号を発生させて、先頭からk番目の位置に挿入する
という馬鹿なベンチマークを作って、リンクリストが遅いなどと言っている
のだろう。
そんなことすれば遅くなるに決まっているが、彼は馬鹿なので分からない。 数学脳を持ってない人にヒントをかいておくと、
リンクリストは、途中への挿入は O(1)で可能だが、
先頭から k 番目という番号を指定した位置への挿入は、O(N)の時間が掛かる。
こういうベンチマークを取って論文にしてしまうような人は、
プログラミングもコンピュータサイエンスにも全く向いてない。 アメリカの大学生の非常に多くのがポインタやアドレスの概念が理解できないらしい。
この人もそれに近い状態だから、途中への挿入を、先頭からの番号で指定すると言う
発想しか出来ないのだろう。
ポインタが何故頭のいい人に好まれるか、そういう人種の人にはわからない。
そして、間違ったベンチマークを大真面目に論文にしてしまう。 >C++のSTLは設計は馬鹿なので、先頭から k 番目に挿入するなど言う
>馬鹿な統一関数がある
え?ここ見る限りそんなのないけど
https://cpprefjp.github.io/reference/list/list/insert.html DDRメモリのセットアップタイムをググったらcrucialが判りやすい資料を公開していた
ttps://www.crucial.jp/articles/about-memory/difference-between-speed-and-latency
これはメモリ単体での値だから実際にはCPU内キャッシュの探索時間、バスの調停時間
メモリコントローラの動作時間が積まれる。L3まで探って未ヒットだった場合CPUが3GHzとしても
30サイクル以上は待たされそう
今時のPCで使用されるプロセッサはL1からのロードですらノーウェイトではないし計画的なロードは超重要 先頭や末尾への挿入削除だけならVecDequeでよくね >>123が参照してる記事でもっと詳細あったわ
https://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html
こっちは、挿入が挿入箇所のサーチも加わったことを断った上で比較してますね
サーチを加えてもデータサイズがでかい・コンストラクタのコストが重い場合はlistが有利っすね
挿入位置のサーチの分のコストを含めるかは難しいところだけど、先頭・末尾以外の一定位置にだけ挿入するってシチュエーションはそうそうないだろうし、
この程度の比較でいいんじゃねーのかな >>132
イテレータであらかじめ挿入位置を探しておくんすよ
その操作はO(n)かかって、その後insertメンバ関数で挿入する 実際には、挿入箇所のサーチなど必要無い事が多いので、リンクリストが速い。
テストする人は馬鹿なので、実際的な「ランダム」の意味が分かってない。 >>135
>挿入位置のサーチの分のコストを含めるかは難しいところだけど、先頭・末尾以外の一定位置にだけ挿入するってシチュエーションはそうそうないだろうし、
>この程度の比較でいいんじゃねーのかな
違う。
サーチが必要なく、分かっている途中の場所に挿入するケースが圧倒的に多い。 >>133
それはリンクリストだけの問題ではなく、>>122のように、動的配列でも
現実的には事情は変わらない事が多い。
動的配列は、要素のサイズが小さくて、Heap領域へのポインタなどを中に持ってない
場合のみ、リンクリストに勝てる。
たとえば、この条件に当てはまっている典型的な例として、文字列を文字の集合とみなした場合や、
3Dの頂点座標などは、(動的/固定)配列で持っているのは正しい判断で、リンクリストで
持つべきではない。
たとえば、要素がメンバとして、CStringやstd::stringなどの文字列を持つ構造体の場合は、
>>122の状況が生じるので、要素を配列で持ってもキャッシュミスは避けられない。 STLの設計も悪いが、リンクリストに対するランダム挿入のテストで、
ランダムな整数kを求めて「k番目の要素」の直前に挿入するような
馬鹿なテストをしている場合、リンクリストは、先頭からk番目までを
丁寧に辿らなければならないので、その時にO(k)の時間がかかる。
全体の要素がN個の場合、このようなランダムの場合、平均でN/2に比例した時間が
掛かるのでO(N)と表現される。
しかもこのとき、要素をk個もたどらなければならないので、キャッシュミスがあったら
かなりの時間が掛かってしまう。
逆に、動的配列の場合は、先頭からkまでをたどったとしても、キャッシュミスは軽微。
しかし、現実の途中の挿入は、このような「辿る操作」が全く必要無い事が多いので、
リンクリストは速い。
要素を識別するために、先頭から「k番」という番号で行うのは、「配列流」で
あって、ポインタが理解できない人には、それしか方法が分からないが、リンクリストは
そのような方法で要素を識別しない。
そして、その識別方法こそが、リンクリストが配列よりも圧倒的に便利であることに繋がる。
ポインタはとても賢い方法なのだが、頭が悪い人には理解できないので、どうしても、
先頭からの番号でしか要素を識別したがらない。
そしてそのことこそが、あらゆることを遅くし、プログラムを見通しの悪いものにしている
ことにも気づかない。 リンクリストをサーチする場合
1.次の要素のアドレスを取得
2.次の要素のメタデータを取得
3.データを評価
4.アンマッチだったら1に戻る
を繰り返すので、メモリ配置次第ではランダムアクセスになりやすく
無策だとキャッシュミスを発生させやすいって話じゃないの? >>141
でも、要素の中にstd::stringなどを入れていた場合、そのstringの中味は、
Heap領域を指しているので、どうせ動的配列でもキャッシュミスは生じる。
だから動的配列がサーチで有利になるのは要素がトリビアルな場合のみ。
また、サーチしても、削除などを行うととたんに動的配列は遅くなる。
この場合、O(N)個のCopyまたはMoveが生じる。Moveでも
コピー動作が全く生じないわけではないので(途中の)1個の要素の削除でも、
動的配列はO(N)の時間が掛かる。
一方、リンクリストは、O(1)。
読み取りが中心になる場合は、動的配列はもちろん速い。 >>141
リンクリストをサーチするのは pure Cで書けばこんなに簡単で、物凄く効率が良い:
CNode *pNode = pTop;
while (pNode != NULL ) {
(pNodeを検査);
pNode = pNode->m_pNext;
} >>141
同じO(n)でもLocalityの違いでVecとLinkedListじゃ桁違いの差が出るよって話
「無策だと」って言っても現実的にLinkedListをVecと同じようにCache Friendlyにする方法ないよね? 実際にテキストエディタでも作ってみれば、LinkedListの優秀さが分かる。
行数が大きくなった場合、動的配列では遅くてどうしようもない。 なるほどね
テキストエディタという具体例があったか エディタの場合はO(n)の探索じゃ困るからLinkedListで作られてるメジャーなのないでしょ
Piece Table, Gap Buffer, RopeのいずれかでRope以外は基本的に配列を中心に実装されてる
VS Codeの例
https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation
Heap ManagerとかMemory Allocatorみたいなのは内部的にLinkedList使ってる >>148
>エディタの場合はO(n)の探索じゃ困るからLinkedListで作られてるメジャーなのないでしょ
「探索」とは何のことか知らないが、
「検索」に関しては、ArrayListでもLinkedListでもbig O表記は変わらないが。 StackOverflowも、これに関してはデタラメ。
実測してLinkedListの挿入が遅いとした人のコード見てたら、
ノードの個数Nの値が、1から100までしかならないようになっていて、
それを、以下の様に外側から100000回くらいループした、二重ループになっていた。
for(100000回のループ) {
リストの変数を作成
for(100回挿入するループ) {
}
}
これだと、LinkedListのNodeがHeapから作製される遅さばかりを測定しているだけで、
全く、LinkedListの真骨頂であるところのNが大きな時の挿入はテストできていない。
StackOverflowはとても高度なことを答えている人もいるが、この件に関しては、
レベルの低い人の書き込みが目立っている。あれを信じてはいけない。 >>141がかなり素朴にキャッシュミスの話をしてくれてるのに
平然と>>143を返すあたりでもうコイツから得られる有益な情報は無いので解散 >>151
LinkedListには、メタデータなんて無いから、話がそもそもかみ合わなかったので
初歩的な情報を提供したつもり。 Intelの最適化マニュアルを見ると、不規則なメモリアクセスで
ハードウェアプリフェッチが有効に機能しないシチュエーションでは
ソフトウェアプリフェッチが有効であると書いてある。つまり
>>141 2.5 次アクセスするメモリに対しプリフェッチ出来る命令を実行する
みたいにすればメモリのランダムアクセスに起因するレイテンシを短縮できる
あとサーチの場合メモリ配置の局所性以外の要因でも配列とリンクリストの速度差は発生する
リンクリストの場合メモリ帯域の一部をアドレスのロードに取られるのでデータのロードに使える帯域は減少する
配列の場合はレジスタにおいたアドレスを使ってロードできるし
ストリング命令が使えるプロセッサであればサーチ命令を使用する事も出来る Twitterによくいるトンチンカンな知識の割に
謎の上から目線で口上垂れてる同類だな Elixir では、リストへの全走査が主体。
フィルターとか
ランダムアクセスではない。
全探索が基本
全探索はリスト、ランダムアクセスは配列。
リストは、次の要素しか分からないから
「1, 2, 3, 4, 5」という要素があって、奇数だけをフィルタリングしたら、
「1 -> 3 -> 5」みたいに、リンクをつなぎ直す。
2, 4 はGC の対象になる
こういう全走査では、リストが圧倒的!
これが動的配列なら、2の削除で、345 を前に移動して、
4の削除で、5 を前に移動してと、コピーの連続になって大変
だから、Elixir では、リストが主体になっている。
関数型では状態を変えず、パイプラインで、新たな要素を作っていくのが基本
全走査が基本で、ランダムアクセスしないからだろう >>153
次の要素のアドレスが把握できたタイミングから
そのアドレスにあるデータを利用するまでにプリフェッチが完了するような場合なら
微妙に速度が向上する可能性がないとは言わないが
それは>>135の記事にあるようなVecとLinkedListの比較で意味のある違いにはならないでしょ >>148
>Piece Table, Gap Buffer, Ropeのいずれか
なにそれ面白そう VS Codeの異常に早い検索はそれで実現されてるのか IteratorでItemがimpl Futureをしてる型を返すっていう実装したいんですが、方法が分かりません。
どのように解決すればよいのでしょうか?
while Some(fut) = fut_iter.next() {
let result = fut.await;
} >>154
数学が分からん人には、LinkedListの優秀性も理解できない。
実験しても実験の仕方が間違っているので間違った結果になっているが、
本人が気づかない。
C++のStrousstrup氏も間違っている。
集団幻想。
それだけ数学的なことは才能が必要だということだ。
多数決では、ArrayListが圧勝と言うことになってしまっているが、それは
本等は間違い。 数学的なことは、99%位の人が正しく理解できないので、ベンチマークテスト
のプログラムも1%位の人しか正しくかけない。
だからデタラメな集団幻想が、LinkedListが過小評価に繋がっている。
まだ、雑誌などでは学歴フィルターというか、頭の良さフィルターをかけて入社
させない仕組みがあるので、あまり間違ってはないが、ネットはめちゃくちゃ。
見ていたら、論文にまでしてしまっているひとまでいるようだが、間違っている。 >>95
グラフ表現とかでもlinkedlist使わんの? あーあっち側の人すかー
有意義な議論ができるかと思ってた
皆さまご苦労さまです とりあえずベンチマーク取ってみたらええやん。。よくいる種類の馬鹿だよね。
こういうタイプはフィボナッチヒープとか大好きなんだよな。 ArrayListおじさんはArrayDequeをどう評価するの? >>162
グラフは何かしらのツリー構造を使うからLinkedListは使わないでしょ https://ideone.com/lH56m8
ArrayListとLinkedListを思いつくままに比較した。
結論は特に無し。 https://ideone.com/O4aPii
sumi2 1,222,328 164,294,013 (1.000000:134.410742)
を追加。 まだ続くなら、動的配列とリストの具体的なベンチマークのコードを載せてくれ
rustが好ましい >>167
Javaでは、末尾追加の aitと、途中削除の rit、先頭への追加 は、LinkedListの方が
速いという結果だね。
この場合、要素数が2万個だけど、もっと多くなると理論上、その差はいくらでも開いて行く。
また、単純に全要素を足すsumitとsumforでは、0.25%, 1.4% の差しかない。
逆に、末尾追加のalastは、ArrayListの方が4.8倍速い。
これはLinkedListの場合、1要素ずつメモリアロケーターを呼び出しているので遅くなっており、
予想通り。
しかし、先頭追加のa0とalastの時間差が、LinkedListではほとんどない(理論上は全くないのだが)
のに対し、ArrayListでは82倍もあるのも予想通りの結果。
LinkedListは、先頭、末尾、途中のどこを操作しても、理論上、時間差が(ほぼ)ないが、
ArrayListは、大きく違ってくるというのが理論上予想されたことで、このベンチマークは正しく
それを反映している。 >>170
なお、末尾追加も、同じサイズのノードに限定したものなら、メモリアロケーターが
劇速のものが作れるので、LinkedListでも、ArrayListに匹敵するくらい速度が
出るように作れる。 >>171
間違った。
匹敵どころか、要素数が多くなった場合、LinkedListが追い抜く。 この結果は、JavaのLinkedListが、素直にLinkedListを素朴に実装しているから
出てきたもの。
一方、STLは、設計が悪いので初心者が誤解を招く結果が出てしまう。
それは、追加する場所をアドレスではなく、先頭からの通し番号で指定する
ことが標準になっていたりするから。 >>173
> 先頭からの通し番号で指定することが標準になっていたりするから。
なんでそんな間違った前提を置いてるんだ?
C++ の std::list にそんな機能はないってことをたびたび指摘されてるが、
あんたは今までリンクリストの優位性がどうこう言ってたのとは別の人なんか?
(いや、そんなはずはないよな、こんな荒らし野郎が何人もいるとは思いたくない。) Javaはmalloc/freeが超速いので、他の言語よりはLinkedListに優しい GC言語は領域の再利用をgc時に行うからnewの時に空きを探す手間が少ない。
単純に端っこから割り当てていくだけ。 >>174
あ、記憶違いだったわ。
STLが汚すぎて。 https://ideone.com/NZEWm8
vectorとlistも比較した。
listのsumiとsumi2が小さすぎるので何か間違ってる予感。
全体的に古臭い書き方ですまそ。 ゲームエンジン・データベースなどの本には、メモリプールを作る方法が、よく載っている
同じサイズの要素を、まとめて確保して、そのプール内で管理する方法 >>167
実行順やJITの兼ね合いがあるから
ちゃんとやるならJMHで測ったほうがいいよ >>181
システムコールの呼び出し回数を押さえるため?
でも通常のmalloc/freeもプロセス再起動されなければ領域再利用されるよね。
なら最初にmallocでガバっと取って、実際に使う時にfreeしてmallocしなおせば良くない?
ゲーム専用機の場合はシステムのAPIもいまいちだったりするから自前でメモリ管理もありだと思うし、DBの場合もキャッシュやら共有メモリやらmmapしてどうたらで自前で管理したいのもわかる。
でもそれ以外で普通のOS上のアプリで自前でメモリプール管理するメリットってどれだけあるの? 予め決まったサイズを確保することが多いから、予めまとめて確保しておいて数珠繋ぎにしておけば最速で出し入れできる 16msecの間にすべての処理を完了しないといけないからmalloc呼び出しなんてありえないよ >>167
このデータの作り方だとLinkedListでもかなり連続したメモリ領域が使われてる可能性が高いような気がする
Javaの場合はList<int>じゃなくList<Integer>で
値を使うケースだとポインタを辿る必要があるのでそれも結果に影響しそう >>159 に答えれる方いませんか?
ここはリスト議論のスレッドですか? >>184
情報サンクス。
JMH勉強になりました。存在すら知らなかったです。
>>188
AutoboxingとUnboxingも大事なところで平然とやりまくってるので、
こちらもご指摘のとおり結果をぼやかしちゃってると思います。
LinkedListはなるべく不連続にリンクされたデータを準備してみよう!
という心意気は当初あったのですが、サボりましたw 挿入が必要なら普通はヒープ組むのになんで誰も突っ込まんの? テキストエディタのようなものだと、アプリを起動して編集し始めた時から、
新しく追加したデータに関しては、対応するノードは、Heapからアロケートしても、
連続したアドレスに載っている。
ロードした直後、最後の行のノードのアドレスと、編集で追加したノード
のアドレスが近い。
編集で追加した行の直前直後のノードのアドレスと、編集で追加したノードのアドレスは
不連続である。
しかし、キャッシュは、何も、最後の1つのページだけしか覚えておけないわけでなく、
1000種類位は覚えておける。
だから、このくらいだと、どちらもキャッシュに乗ることになる。
なお、ArrayListの場合、途中へ追加すると、半分近くの要素に対してコピー動作が
必要になるが、その際、キャッシュを全て使い切ってしまうことがある。
配列の全データが100MBだとすると、このコピー動作のために100MB分のデータが
いったんキャッシュに読み込まれる必要がある。
キャッシュはL3ですら8MB程度しかないので、これだと全くキャッシュが足りなくなる。
その点、LinkedListは、このようなキャッシュ汚染は生じない。 >>192
さらに、100MBのようなデータだと、ArrayListで全データを巡る際でも、
キャッシュミスもキャッシュ汚染も生じる。
だから、ArrayListがキャッシュで有利と言っても、現実的には2MBくらいまで
がその優位性は維持できない。
そしてLinkedListも実際的な用途では、>>192に述べたような状況になるので、
キャッシュミスは余り生じない。 >>193
テキストエディタの例だと、100万行のファイルを読み込んだとしても、
実際に閲覧したり、書き込んだりしたい場所は、数箇所に集中することが
多い。
LinkedListの場合だと、編集時に行を挿入する場合、全データを移動する
必要が無いので、1行当たり、数10バイトくらいのコピーで済む。
この場合、キャッシュ汚染はほとんど生じない。
一方、ArrayListだと、100万行のコピー動作が必要になり、その際に
キャッシュを浪費してしまう。 L1,L2はkbyteオーダーだろ
余裕でキャッシュミスするわ
>>189
一言多いってよく言われないか? >>195
>L1,L2はkbyteオーダーだろ
>余裕でキャッシュミスするわ
そこは、ArrayListで挿入する時の移動動作でもね。 なんでテキストエディタの例でArratListが出てくるんだ >>195
すみません。
スレチ馬鹿が多いので言わないと分からないかと思い書いてしまいました。 CSのスレでも立てればいいのにな
無駄なマウントとプライドで議論になってないじゃん Rust 初心者ってか始めてもないけど、
fn main() {
println!("Hello, world!");
}
これってセミコロン要るの? >>204
そのケースはコンパイラー的にはどっちでもいいけど
println!の戻り値をmain関数の戻り値として意識的に扱いたいわけじゃないだろうから
セミコロン書くほうがいいと思う >>205
なるほど。
たまたまprintlnの戻り値が()だからエラーが出ないんですね。 return省略は関数型なのか?
関数型をふりをするなら {} を省略して = で書くとかでは lispのprognみたいな感じじゃね。
セミコロンを書くとその後に空の式があるようにみなすのはイケてないと思うけど。 expressionをstatementにするのがセミコロン
statementは`()`として扱われる
セミコロン不要にして必要に応じて`()`を明記するスタイルのほうがイケてたとは思う
returnを省略するのは慣習
関数を含めて式が値に評価されていくというメンタルモデルなので
”return文”という感覚ではないのかもね C++系言語に見た目を近づけるという設計意図があるから()を明記するという判断にはならなかっただろうとおもう 戻り値型の宣言にも -> () っていちいち書かなくていいしなあ
そういうもんだとしか 単純に、セミコロンの有無だけで区別するのが視認性が良くないんだよな。
エディタの方で違いを目立たせられたりしたらいいけど。 >>214
クロージャならやってくれるから技術としては可能だけど、
関数として定義するなら関数仕様としてimpl Traitまでは書こうねということと解釈している >>215
いまさらどうにもならないが、使いはじめの頃は、もっと視認性のあるフレーズ使ってくれてたらなぁと思ってた。
例えば、F#の
hofe |> ignore
なんかは、冗長ではあるが逆に視認性も良く、捨てる気満々の書き方で気に入ってる。 そういえばelse節の無いif式は()に評価されるんだっけか コンピューターはともかく、人間にはreturnくらいの文字的冗長性があった方が視認性がいい。 ifは末尾}に;不要なのにletは末尾}に;必要なのだるい >>220
returnがあればearly returnだと識別できるのでその意味では視認性は高い
ただセミコロンというC系言語経験者が注視しない記号に新しく重要な意味をもたせたから戸惑う
>>221
ifブロック末尾のセミコロンは常に省略できるわけじゃない
https://doc.rust-lang.org/reference/statements.html#expression-statements
セミコロンがないと意図通りパースできないケースってほとんどないと思うので
そのうちJSのASIのようなものでセミコロン不要になる未来もある気がする 個人的にはセミコロンうんぬんよりifの中括弧が苦痛
/* c */
#include <stdio.h>
#define min(a, b) ((a) < (b) ? (a) : (b)) // スッキリ
int min2(int a, int b) {return a < b ? a : b;} // ややスッキリ
int min3(int a, int b) {
if (a < b) return a; else return b; // スッキリ?
}
int main() {
printf("%d ", min(3, 2));
printf("%d ", min2(3, 2));
printf("%d ", min3(3, 2));
return 0;
}
// rust
fn main() {
let min = |a, b| if a < b {a} else {b}; // 中括弧が嫌
//let min = |a, b| if (a < b) a else b; // これならスッキリ
//let min = |a, b| if a < b then a else b; // あるいはこれ
println!("{}", min(3, 2));
}
(* ocaml *)
let min a b = if a < b then a else b (* スッキリ *)
let () = print_int (min 3 2) はいはいdangling else dangling else Goもそうだけど、条件式に括弧を使わないのがいまだに慣れない。 BASIC は要らなかったから慣れてる。
3項演算子考えたやつは天才。 >>225
本文 (?) の波括弧が必須だから
条件式の範囲は自明 (視認性的に) だってことなんだろうな。 >>225
そのへんとモジュールまわりはPythonの影響かなと思った >>228
PythonというよりRubyだろね
コアチームは過去も含めてRubyコミュニティ出身者が多いから
モジュールはPythonのようにファイルベースじゃなくキーワードで名前空間をきちんと切るし
クロージャの書き方だったりreturnを書かない慣習だったりも他言語に比べて類似性が高い 型システムは ML 系の言語でよくあるやつだし、
そっち方面の影響もあるんじゃないの? >>231
> Ruby: closure syntax
縦棒で引数囲むのはruby由来だったのか if a < b => a else => b っていう変なもんを思いついてしまった
だーめだこりゃ セミコロンとかはEdition上げて撤廃してほしいけど、ここまでRustのOSS書かれてたら無理だろなぁ... Rust, Go, Elixir などの新しい言語は、Ruby の影響が強い。
Ruby で最も良いのは、すべての進数の数値リテラルに、_ を含められること
こういうコメントを書かなくて済む
1000000 // 1_000_000 戻り値の有無がセミコロンだけで区別されている現状をどうにかしないとそもそもセミコロン廃止なんて
無理だろうけど、セミコロンレスってそんなにいいかねぇ?
行の折り返しを間違えて別の文になってしまってもスルーされる場合があるのがなんか嫌。
ASIがあるJSでもメジャーどころのスタイルガイドはみんなASIを信用しないでセミコロン使うことに
なっているし。
pythonだとセミコロン使わないスタイルも多いけど、あっちはインデントで判別できるしね。 >>237
>ASIを信用しないでセミコロン使うことに
ASIを信用してないわけじゃないよ
ASIの仕様はJSの仕様で決まってるから例外的に挿入されない場合もはっきり分かってる
セミコロンを使うスタイルが多いのはミニファイとかを考慮してるから
JSの場合は普通に書いてる分にはセミコロンの有無でほぼ違いが無い上に
セミコロンレスで書いてもリンター使って自動挿入できるから実質書き手の自由
1行に複数文書いてるときでもなければセミコロンに特別な意味はないから気にする必要がない セミコロンは基本的にはあっていいけどたまに}のあとに;必要なやつとかあったりしてこれはイヤ たしかに「ASIを信用しないで」というと疑っているみたいだから「依存しないで」の方が
適切だったかも。
いずれにしても、どのスタイルガイドもプログラマの意図と異なる判断がされる危険を
挙げていて、それを防ぐためには明示的にセミコロンを記述する方が良いと謳っている。
minifyはそれこそminify時にセミコロンを補完すればいいんだから関係ないと思う。 >>236
Verilog は 1985から出来てたけど?
多分、もっと古い言語からあったんだろう。 セミコロン撤廃要望多いとは思えないんだけどRFCとか書いてる人いるのか? セミコロン書き忘れる事は多々あるけど、意図しない値が返ってとかならない(はず)なので別に困らない
それより、Docs.rsに見にくいクレートが有る方が困る、AutoとBlanket以外のShow hidden undocumented itemsを
デフォルトで展開するオプションが有れば良いのに、この議題はどっかで見たような気がする。 >>241
1967のPL/Iあたりからかな?登場時期からするともっと広まってもおかしくなかった気もするけど、16/32ビットリテラルしかなかった時代には需要なかったんだろうね。verilogは何ビットでもいけるから必要だけど。
最近は128ビット型とかBigIntとかでようやく必要になってきたってことか。 rustのAPI documentなんか読みづらい気がする
うまく説明できないけど
型クラスのあたりも見づらい >>240
きちんとした手順にそったminifyだけを指して言ったわけじゃないんだが
GoogleやAirbnbのstyle guideを見ると確かにそういう意図ではないみたいだね
npmやGithubみたいにセミコロンレスのstandard style使ってるところも多いから
「メジャーどころはみんなセミコロンを明示的に書く」というのはちと言い過ぎかな
いずれにしろJSの場合は1コマンドで一瞬で切り替え可能で書く時はどっちでいいから
Rustとはかなり事情が違うと思う >>242
探してみたらRFCあったけどCloseされてた
https://github.com/rust-lang/rfcs/issues/2583
C/C++/G#/Javaあたりから来た人はセミコロンあるのが普通だろうけど
Go/Scala/Swift/Kotlin/Ruby/Pythonだとセミコロンないのが普通なので面倒くさく感じるのよ
RFCのやり取りや↓ここの議論を見るとセミコロンが不要になる可能性はもうないね
https://internals.rust-lang.org/t/make-some-separators-optional/4846 セミコロンレスってフォーマット的な改行と文末の改行を文脈を見て判断する必要があるから好きじゃないなぁ。
一文が複数行になりやすいビルダーパターンとかイテレータアダプタの類いが特に。
入力する側としてはほとんど無意識に打ってるから特に面倒とも感じないし。 IntelliJ使えばセミコロンを殆ど見えないような色に設定できるぞ >>223
ocamlってセミコロン必要じゃなかったっけ? docsのフロント部分は特に強いUXデザイナーがいない感じがすごくする >>251
トップレベルの分を区切るのに;;を使う
ただしletの直前、ファイルの最後、などでは省略できる
https://ocaml.org/learn/tutorials/structure_of_ocaml_programs.ja.html
構文は
https://ocaml.org/releases/4.11/htmlman/language.html
let min a b = if a < b then a else b (* letの直前だから;;省略 *)
let () = print_int (min 3 2) (* ファイルの最後だから;;省略 *) slice::windowsのstrバージョンみたいなのってないのでしょうか。
ようするにある文字列に含まれる連続するn文字を頭から順に返すイテレータを作ってくれるようなやつです。 >>255
ないのでVec<char>を生成してwindowsを呼ぶとか
let cs: Vec<_> = String::from("あいうえお").chars().collect();
let ws: Vec<_> = cs.windows(2).map(|v| v.iter().collect::<String>()).collect(); 文字幅が可変長 (utf-8) であっても windows みたいなことをするのはそんなにコスト大きくないよね?
ふたつのポインタを一文字ずつ進めるだけなんだから O(N) で出来るはず。 アロケートなしだと、
(0..s.len()-n).map(|i| &s[i..i+n])
となるけど自分で-nとか+nとかiとかやるのめっちゃアホくさいしそのうちミスりそう >>258
アロケートなしならこれでもいけるはず。utf8を食わせると死ぬけど
.as_bytes().windows(2).map(|v| std::str::from_utf8(v).unwrap()) アロケートなしっていっても結局collect::<Vec<_>>()するんだからなしって表現は違うくないか collectするとは限らんやろ
ヒット数だけ必要な場合とか Vec<T>って既に有る要素の中身を修正する方法はありますか。
有れば教えていただければ幸いです。 自分が見た本ではvec[0]でアクセスする例は出てなかったと思うのですが
今ネットで見たところ
let mut vec = Vec::new();
vec.push(1);
vec.push(2);
vec[0] = 7
という例がありました。
Vec<T>の要素Tが構造体の場合、
vec[0]のアドレスを参照で受け取ってアクセスするには
let &mut a=&v[0];
a.xxx = yyy;
でよいのでしょうか?
(基礎が分かって無いだけかもしれませんが) >>265
有難うございます。getは載っていたのですが get_mut は知りませんでした。
さらに質問させてください。
Vecに対する[]演算子のメソッド名(?)は何でしょうか? std::ops::Indexとstd::ops::IndexMutをリファレンスで見て >>264
>let &mut a=&v[0];
let a = &mut v[0]; >>267
ありがとうございます。
>>268
なるほど言われてみれば文法的にそうでないと駄目でした。
しまった。 https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a388e403b6cd7afe902a9fd8618b5a65
質問内容とブレてたらごめんなさい TがCopyだと let &mut a = &mut v[0]; ならコンパイル通っちゃうのは落とし穴かもしれない >>270
get_mutをunwrapしちゃうなら普通に &mut v[0] で良いと思う 勉強始めたばかりですが変数のシャドーイングって必要ですか?
なんとなくグローバルに置いた変数もシャドーイングできそうなのですが実害は出たことありますか?
多分ないと思いますが… Which Programming Languages Use the Least Electricity?
https://thenewstack.io/which-programming-languages-use-the-least-electricity/
> Energy consumed Run-time
> C 57J 2019 ms
> Rust 59J 2103 ms
> C++ 77J 3155 ms
> Ada 98J 3740 ms
> Java 114J 3821 ms デバッグやバグ修正に必要なエネルギーコストを加味したらCより効率よくなりそう let mut bt = (0..10).collect::<BTreeSet<_>>();
for e in bt.iter() {
// ここで条件に一致する要素をbtから削除したい
}
こんな感じのものを作りたくなったのですがどうすればいいのでしょうか?
うまい具合にやる方法が思いつかなくて以下のようにやっているのですが、なんというかすごくアホくさいというか・・・
let mut bt = (0..10).collect::<BTreeSet<_>>();
let mut temp = Vec::new()
for e in bt.iter() {
if e == Foo { temp.push(e); } // 削除予定のものをtempに入れる
}
for e in temp {
bt.remove(&e);
} let bt = (0..10).filter(|e| eが要るなら真).collect::<BtreeSet<_>>();
じゃあかんのか btがこの例のとおりのものならそれでいいんですけど、
いろんな状況でbtに要素が追加されるっていう感じです
あと、if e == Fooはちょっと雑すぎましたif is_xxx(e)とかのほうがよいです コンテナのイテレーターのループ回してる間にコンテナの要素を追加や削除は出来ない。これは他のコンテナ(Vecなど)でもそう。どうしてもやるなら内部実装を理解した上でunsafeな方法で。
「いろんな状況でbtに要素が追加される」がループ中なのか何なのか分からないのでどうしようもないが、
let bt = bt.into_iter().filter(|&e| e == foo).collect::<std::collections::BTreeSet<_>>();
で新たなbtを作るか、
もとのbtから要素を削除するにしても
for e in bt.iter().filter(|&&e| e == foo).cloned().collect::<Vec<_>>() {
bt.remove(&e);
}
などでもう少し簡潔に書ける。 BTreeSet::drain_filter が安定化されるのを待とう
std::collections の unatable な機能を含めて切り出した crate とかあれば良いのに retainやdrain_filterについて不勉強だった。ありがとう。 Rust book 構造体の章の以下のコード片なんですが
let mut user1 = User {
email: String::from("someone@example.com"),
email: String::from("someusername123"),
active: true,
sign_in_count: 1,
}
user1.email = String::from("another@example.com");
//コード片ここまで
最後の行でどこからも参照されなくなった元の
String::from("someone@example.com")
は、どういう理屈で解放されるんでしょうか?
もしGC言語なら最後の行でGC対象になるとこですけど。
Rust bookのこれ以前の章で、変数がスコープを外れるときdropが呼ばれることの説明はあったのですが、変数の束縛外れちゃったStringはいつ、どこで? >>286
最後の行でdropされるのは同じ
初期化済みの変数に新しい値を束縛したら古い値はdropされる >>287
ありがとうございます。
変数にバインドされてるヒープ領域がdropされるのはその変数がスコープを抜ける}の時ですよね。
>>286 の
初期化済みの変数に新しい値を束縛してる
user1.email = String::from("another@example.com");
から、
スコープが閉じる}まで、元の
String::from("someone@example.com")
のヒープ領域は解放されないということでしょうか?
user1.email = String::from("another@example.com");
の直後に解放されるのではなく? >>288
https://doc.rust-lang.org/reference/destructors.html
> Assignment also runs the destructor of its left-hand operand, if it's initialized.
だそうです 考えてみりゃ確かにunstableのcrateってめっちゃいい案だな
use unstable::prelude::*;
で全部取り込める上にバージョンあげたらunstableから無くなってstdの方が挿し代わって使われるし 明らかに可読性悪い言語なのだがあと5年くらいしたらこの界隈も気づくかもね それ、「俺様には理解できない」にderefされてます >>291
esolangはさておきAPLとかは難読言語といっても良いかも
あとは暗黙の○○が多い言語や記号が多い言語は初心者にとっては難読だと思うけど
Rustはこれらには当てはまらないと思うけど、どういう点で難読と思ったのか教えて欲しい fn foo(bar: impl Buzz)
というシグネチャは、
fn foo<T: Buzz>(bar: T)
の構文糖なんですよね?
では、
fn foo() -> impl Buzz
を、
fn foo<T: Buzz>() -> T
と書けないのはなぜなんでしょう? >>298
>fn foo<T: Buzz>(bar: T)
>の構文糖なんですよね?
違う >>299
Rust bookにはsyntax sugarと書かれていたのですが…
https://doc.rust-lang.org/book/ch10-02-traits.html#trait-bound-syntax
> The impl Trait syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a trait bound; it looks like this:
>>300
ありがとうございます。
Rust bookはあんまり信用できないのかな… >>301
マジか
どっちも書いてる人は同じだから
引数ポジションについては細かい違いはあってもシンタックスシュガーなのかも
ただ戻り値ポジションの場合は
ジェネリックでは書き直せないから確実に違う 記号が多い言語は英語の苦手な日本人には有利だ
英文に近づけようとする言語は不利だ LISPかな。まあ記号と言っても括弧ばっかりだが。 「Lots of Isolated Silly Parentheses」の略だからな。 >>300
読んでて知ったけど::<T>のことturbofishっていうんだ
かわいい The name "turbofish" was made up by reddit user deadstone in 2015, and has since caught on in the Rust community, being used even in the official documentation.
「turbofish」という名前は、2015年にredditユーザーのdeadstone氏によって作成され、それ以来Rustコミュニティで定着し、公式ドキュメントでも使用されています。 function<>()の方が良かったけどね。パーサーの複雑性があって解決されてなく、もうここまで広まったしいいやってなってるけど >>301,302
型制約と存在型じゃ概念が違うから構文糖は語弊がある。
生成するコードはどちらもモノモーフィックな関数吐くけど存在型は第一引数の違いだけでコンパイル時に
ディスパッチ先が一意に決まらないケースが有るからマルチメソッドを直接サポートしない弊害があるかな。 Internet Archive、Flashコンテンツをアーカイブ プラグインなしで21年以降も閲覧可能に
https://www.itmedia.co.jp/news/articles/2011/20/news143.html
プログラミング言語Rustで作られたFlashのエミュレータ「Ruffle」を使うことで、Flashプラグインをインストールしなくても、WebAssembyが動作するWebブラウザさえあれば動作するとしている。 すげえなww
でも先人の苦労の作品が残ってよかった Rust bookのDropトレイト解説のページ ( https://doc.rust-jp.rs/book-ja/ch15-03-drop.html ) で質問です。
以下のようなコードなのですが、
struct CustomSmartPointer {
data: String,
}
impl Drop for CustomSmartPointer {
fn drop(&mut self) {
println!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}
fn main() {
let c = CustomSmartPointer { data: String::from("my stuff") };
println!("CustomSmartPointers created.");
}
これ、dropの実装部分にprintln!しか書かれてませんが&self.dataの処理は書かなくてよいのでしょうか?
例えば、println!の下に、
drop(&self.data);
のように。
どちらかがコンパイルエラーになるならいいのですが、書いても書かなくてもどちらでも問題なくコンパイルが通ってしまい、困惑しています。 >>317
もう少し細かい話はこの辺に書いてあるよ。
https://doc.rust-lang.org/std/ops/trait.Drop.html
簡単に言えばそのdataは勝手に解放されるからdropは不要。
解放以外で何か処理したいなら書けばいい。
drop(&self.data)としたとしても、それは参照を作ってその参照を即座に破棄してるだけなので特に意味はない。
本当にdataを解放したいならdrop(self.data)になるけどこれはコンパイルエラーになるはず。 あ、最後の行のは多分deref抜けてるな。
いずれにしてもdropするなら所有権を取る必要があるけど、
&mut selfからdataの所有権を取る方法はないので
正しくdropするコードを書けばエラーになるはず。 >>318-319
おお、
drop(self.data);
でも
drop((*self).data);
でも同じ、
cannot move out of `self.data` which is behind a mutable reference
エラーでました!
スッキリしましたありがとうございます。
std::mem::dropの実装って
pub fn drop<T>(_x: T) { }
だったんですねぇ… Rust bookのRefCell解説のページ ( https://doc.rust-jp.rs/book-ja/ch15-05-interior-mutability.html ) で質問です。
以下のようなコードなのですが、
pub trait Messenger {
fn send(&self, msg: &str);
}
pub struct LimitTracker<'a, T: 'a + Messenger> {
messenger: &'a T,
value: usize,
max: usize,
}
impl<'a, T> LimitTracker<'a, T>
where T: Messenger {
pub fn new(messenger: &T, max: usize) -> LimitTracker<T> {
LimitTracker {
messenger,
value: 0,
max,
}
}
// 以下略
pub struct LimitTracker<'a, T: 'a + Messenger> {
の行でトレイト境界に
'a + Messenger
を指定しているようなのですが、
このような書き方今までに出てこなかったので試しに
pub struct LimitTracker<'a, T: Messenger> {
と書き替えてみたところ、警告もなしにコンパイルできてしまいました…
これ、何の意味があるんでしょう? &mut TがCopyとCloneをimplしていないのは理解しているんだけど
let a: &mut i32 = &mut 0;
let b = a;
dbg!(a);
これがaがムーブされてエラーになって
let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
dbg!(a);
これがエラーにならないのはナンデ? >>325
b が使われないことはわかってるので無かったことになる。
b が使われるなら借用中ということでエラーになるよ。
↓ これはエラーになる。
let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
dbg!(a);
dbg!(b); これは僕もエラーにしてほしいなあ
何か深い理由があるんだろうけど… let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
dbg!(b);
dbg!(a);
これをOKにしたいんだから3行目が無くてもOKなのは必然 エラーにしたい理由がよく分からんな。
実際bを使ってないんならエラーになる意味がないし、
typoでbを使い損ねてるならbが未使用のwarningは出るから気付けるし。 >>329
えっ? て思ったけど確かに通った……
どっちも同じ&mut i32に見えてライフタイムが違うのか fn noop<T>(t: T) -> T {
t
}
let a: &mut i32 = &mut 0;
let b = noop(a);
dbg!(b);
dbg!(a);
これはエラーになる
let a: &mut i32 = &mut 0;
let b: &mut i32 = noop(a);
dbg!(b);
dbg!(a);
エラーにならない
ナンデ? 俺も↓これみてやっと分かった
https://github.com/rust-lang/rust/issues/35919#issuecomment-304130115
https://stackoverflow.com/a/58587870
関数のシグニチャの場合を含めて型が明示されてれば
&mut T -> & mut Tの場合でもimplicit reborrowが発生してmoveじゃなくなる
(auto-reborrowやreborrow coercionと呼んでる人も)
今まで気にしたことなかったわ Type Coercionの一貫
ここに少し理由が書いてある
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/coercion/index.html
↓これも同じ理由でエラーにならない
let a: &mut i32 = &mut 0;
let b = a as &mut i32;
dbg!(b);
dbg!(a); 最後にアクセスしたところで借用が終了すると思えば特に違和感はない 変数宣言時に決まらず、今後スコープが終わるまでに使われるか使われないかで変わってしまうのか >>334
>&mut T -> & mut Tの場合でもimplicit reborrowが発生してmoveじゃなくなる
stackoverflowの方でも説明されてるけど、&mut T -> & mut Tじゃなくて&'a mut T -> &'b mut Tだな。 implicitにする必要あった?
便利さより明示・明確で行って欲しい >>334のstackoverflowのコメント見れば必要だとしか
間違えたら単にコンパイルエラーになるわけで imple Trait for Something のTraitとSomething、逆の方が良かったなぁ
トレイトはまとめてモジュールにされることあるからimportしてからstructの直下でimplするからimpl struct with traitのほうが可読性高い、git的にも綺麗な差分の表示にもなるし
これなんか明確な理由とかないのかな? 昔は impl Struct :Trait {} だった気がする
: だとどっちがどっちかわかりにくいみたいな議論はあったような あと impl Struct with Trait だと Struct "を" 実装すると読めるのがイマイチな気はする impl Struct with Traitだと複数書くと同一Structを何回もimplすることになってちょっと変かも
このあたりはネイティブだと「てにをは」がおかしい感じに見えるのかもね lifetime関係で文句言われまくって暗黙にした部分が多いんだろう。。そんな輩にrust使わせる必要なんてないのに。 適当なライフタイムパラメータをつけるとコンパイルできることもあると学んだ >>296
可読性と言うか記述性が悪いし、そもそも厳密な仕様が公開されていない
部分が多い。例えば後者についてはライフタイムとか。 >>294
実際には沢山あって、例えば、makefileやUnixのシェルスクリプト、BATファイル、
Perlの関数呼び出しなんかがある。 >>352
具体的な記述例上げてくれないと何の説得力も無いぞ いつものヤバイ人だってすぐわかるだろ
荒らしの相手をするのも荒らしだぞ Cを日常的に使っていた人がRustに移行しようとするとやりたいことが出来なくて
馬鹿馬鹿しくなる。
数学的には完全に安全な書き方なのにRustには怒られる。 Rust by Example によれば
drop が (自動で) 呼ばれるのは「スコープの終わり」と書いてあるけど、
それは変わってないと考えていいよね?
最終のアクセスがスコープのまんなからへんだったとしても、
drop はスコープの最後ってのは今でも保証されるんだよね? 数学的に完全に安全であるって証明を必要十分な早さで必要十分な量のコードに対して出きる人なら
おとなしくC使ってた方が良いんじゃないですかね だってあなたがここに残っても得られる物何もないでしょ アメリカでは人気言語なんだろ?
つまり問題なく安全に使えてるってことだよね 数学的にもOKでも、書いてるのはコードなんだからプログラミング的にもOKじゃないといけない
っていうマジレスでいい?
言語には仕様があるわけでどの言語でもそうだろ。
そもそもプログラミングしない方がいいよ、数学でもしてりゃいいじゃん コンパイラが証明できないけど人間が証明できるときのためにunsafeがあるんだから使えばいいのに 数学的には完全に安全ww
こんな低脳ワード使ってるやつ相手にして君たち頭おかしいんとちゃう? まあrust使ってれば完全に安全とか言い出す馬鹿もいたしどこにでも馬鹿はおるわ。 色々調べて学んでみたが個人的にはRustは好きな言語ではないし
本の帯に書かれているようなC/C++の代替になるようなものではない。
メモリー安全なのはポインタが理解できない人向け。
Ruby/Puthon/JSのようなスクリプト言語的な使い方ならある程度できそうだが
それらより遙かに難しくなっている側面が有ることも否めない。
C/C++のように自由にデータ構造を作るには向いていない。
C#やJavaは速度は落ちるが、C/C++のコードを容易に移植できたが
Rustは出来ない。 >>384
C#やJavaは、データ構造やアルゴリズムを自由に作りやすいC/C++の自由さを
速度やメモリー効率を落とすことで初心者やポインタが理解できない人でも
手に入れることが出来る言語であった。
RustはC/C++と比べて効率は落ちにくいが C/C++の自由さは手に入らない。
ポインタを良く理解している人であってもRustのsafeモードでは独自の
データ構造やアルゴリズムを作るのは非常に難解。
なぜならライフタイムやBox<T>などの仕様が明言されて無く不明確だから。 >>384 6iyAwzKw
>>385 6iyAwzKw
せっかく関心しかけたのに、自演で信頼性を損なうな >>388
いや、実際に関心する内容があったんならそれはそれでいいんだが
あと別に自演失敗したとかじゃなく、Twitter的な感じでリプライで補足しただけでは
別人を装う気は微塵も感じられない この人ほんとゴミやな
Rustは優秀な老害フィルターかもしれん 嫌いなものを無理に使う必要ないんだが、それを何度も何度も言いに来られてもな
説明しても聞く気ないし 具体的に何ができないか言ってくれないとただのお気持ち表明でしかない リングバッファ実装でさえunsafe使わなきゃ無理だろ。 リングバッファにunsafe必須とか正気か?
何も分かってないだけじゃん 仮に unsafe 必須だとしてそれがどうだっていうんだ? Vec使ったsafeな実装もできるだろうし、
パフォーマンスを求めるなら直接allocのAPIを叩くunsafeの実装もできる
dogmaticにならず目的に応じて適切な手段を使い分けられるというRustの良いところの例だと思うが
なんでunsafe使ったら負けみたいな思考になるのかが分からない むしろ libc crateだけで作ればいいんじゃないか unsafe使ったリングバッファで数学的に完全に安全てw
自分の書いたロジックをコンパイラが検証してくれないって話だったのかよ safeとunsafeを混ぜられるところはまさにRustの旨味そのものなんだが >>404
unsafeじゃない実装もできるいうてますやん 全部unsafeで常に安全性に気を使わなければならないC++
一部のunsafeな箇所の安全性にさえ気をつければ、大部分のsafeな箇所はコンパイラに従うだけで安全になるRust
C++の方が楽と感じるのはなぜ?使い慣れているから?コンパイラに叱られないから? 数学的にというがそれはどうせ高校までの数学でしょ?
大学で教わった群論や離散数学を含んでるのか? 数学的に安全というのはCoq使って検証したとか
言ってもらわないとなあ RustBeltやRustHornみたいな取り組みに期待したい miriは普通に使えるんじゃない?
といっても実行パスでUB踏んでないか見るだけだから
RustBeltみたいな証明とは違うけど >>406
はっきりいえば、頭がいいから。
学生時代、ほとんど数学は満点だった。 >>414
私は馬鹿だから、あなたがとってもうらやましいですね… >>414
C++の言語仕様完全に理解してそう。すごい >>406
普通にc++使ってれば安全性に気を使わなきゃならん部分は一部だとわかるし、
それがどういう部分かと言えばrustがunsafeで書かなきゃならん部分だからだよ。 >>417
それでもミスるのが人間。そういった経験からシステム的にミスを無くそうと試みているのがrust。
それをわかった上で俺はミスしないって言ってるのはただの経験不足か、プログラムを全然組まないやつだな。 >>417
(とりあえず unsafe を使う必要がないようなコードで)
Rust を使って最初からエラーなしで通すことが出来るんか?
それでどこかで引っかかるようなら C++ でもたぶん出来てないぞ。 cd ~/.cargo/registry/index/github.com-1ecc6299db9ec823
git pull https://github.com/rust-lang/crates.io-index.git D言語のリファレンスって平易な英語で書かれていて、自分でドキュメントを書く時にすごく参考になる >>418
俺は高IQで、数学が得意だったので、C++で何10万行のプログラムを書いても、
経験的にメモリ関連のバグが起きる確率はとても低い。
一般プログラマには当てはまらないかも知れないが。 >>425
メモリ関連のバグは「確率が低い」では全然だめですよ、バグを作ってしまうことは仕方ないにしても、最初から根絶を目指さなくてはいけないかと
私なら、最低限 new/delete はオーバーロードしてラッパを書き 未 delete・重複 delete くらいは確認しておきますね
まあ、最近はお気楽に unique_ptr, shared_ptr で妥協することがほとんどですが、weak_ptr はちょっと怖くて使わないようにしています… >>425
あなたのプログラムでバグが起きる確率が低いことはどのように検証したのですか? そう、未だ気づかれていない大量のバグが潜んでいるのだった みんな同じじゃないぞ。
頭にも才能があるのを忘れるな。
そうでないと高IQ者が活躍できない。 >>432
>>431
たしかに高IQの人の言ってはることがさっぱりわからなくて…
というか、高IQ だと私が思っていても実は、IQ=100 の人だったりして…
ということで、私のIQは80くらいだと思っています >>433
普通、高IQといえば、IQ=140以上だろう。 >>431
それでメモリ関連のバグの有無はどういう基準で判定してるんですか? QZの方が最悪だ。
自分と自分の周りの価値観がすべてだと思っている。
平均の人々と秀才とはどこまで行っても違う。
言語の好みから何から何まで。
必要としていることも何もかも。 >>438
>自分と自分の周りの価値観がすべてだと思っている。
私は私の持つ価値観以外にも、別の価値観やセンスオブバリューが存在し、かつ、私の持つ価値観よりも優れた価値観が存在し得ることも想定していますが、
私の発言の中に「自分と自分の周りの価値観がすべてだと思っている」とあなたに感じさせた部分がありましたら、是非ご指摘いただけるととても嬉しいです >>440
それって変てこな語法ですよね
数学的に正しいのであれば、それは経験とか履歴とかヒストリーとかにまったく関係なく、
数学的に正しいと証明された時点で、現存宇宙のビッグバン以前、宇宙死以後にも、数学的に正しいのに
ど う し て 「 経 験 的 」 と い う 単 語 を 使 用 し て い る の で し ょ う か ? >>436
年内に会費払わなきゃいけないのを思い出した。ありがとう。 >>436
メンサの人ってどんな人なんでしょう?
一度お会いしたいです
お話しするなかで、私のような馬鹿がもう少し生きやすくなるコツみたいなものが私にも感じられたら(多分理解は無理だと思います…)とても嬉しいですね せっかくのRustスレなのにどうしてこんなカオスなスレになっちまったんだ… from_str を実装しようとしています。
入力となる文字列 (の一部) をスライスとして保持するようなデザインにしたいのですが、
ライフタイムの整合性を取れる書き方が出来ません。
FromStr はそういうことが出来ないように制約付けられたトレイトということなのでしょうか?
それとも工夫してどうにか出来るでしょうか?
やりたいことをコードで言えばこんな感じです。
use std::str::FromStr;
struct foo<'a>(&'a str);
impl<'a> FromStr for foo<'a> {
type Err = &'static str;
fn from_str(s: &'a str) -> std::result::Result<Self, Self::Err> {
Ok(foo(s))
}
} >>450-451
ありがとうございます。
設計を見直します。 高IQの自分は、Cでメモリーマネジメントに悩まされたことは無かった。
一方、Rustはメモリーマネジメントが言語の中心に有り、プログラムの
アルゴリズムや本質的な処理よりもメモリーマネジメントに意識が集中して
しまう傾向がるため、人によるだろうが自分にとっては効率的な言語ではない。 一般プログラマにとっては層ではないかも知れないが、
高IQのエキスパートにとっては、もっと安全に書ける方法を高頻度で天才的に
思いつくが、それはRustのチェッカと戦いとなる。 学習曲線、ライブラリが未成熟、コンパイル遅い、っていういつものやつをみんながコメントしてるだけ
まぁ問題には違いないし改善も試みてるわけだけど >>462
そりゃ細かいのはまだあるだろうが。HKTとか?
300件全部見る気もないのでやりたいなら自分でリストアップしてくれ >>463
453, 454 もその一部に書いてあったものだ。覚えているものだけでも:
・Rustでは、本質ではなくメモリーマネジメントが前面に出たプログラミングとなってしまう。
・もっと良いモデルで書こうとしてもRustが安全性を理解できずエラーになってしまう。
・unsafeモードは悪者扱いされた結果ドキュメントが乏しく進化も遅いため使いにくい。
・長い歴史で実績の有るクラスの継承や例外機構が使えない言語設計。
・抽象化が深すぎて最適化を前提としているので最適化しないと極端に遅い。
・抽象化が深すぎるしマクロが多用されているためデバッガが使いにくくprintfデバッグ中心で行かざるを得ない。
・正確で詳細な言語仕様に乏しいためシステムプログラミングや組み込みには向いていない。
・コンパイラの多様性に乏しい(今のところrustc一個しかない)。
・ターゲットCPUがLLVMのものに限られるため、組み込みには向いていない。
・グラフィックが弱い。
・OpenGL、DirectXと併用するのが難しい。
・コンパイルが極端に遅い。
まだまだある。 >>464
[追加]
・抽象化が深すぎるため最適化無しでは極端に遅くなるため、デバッグ時も
最適化しなくてはまともに動作確認できない。これもデバッガが使い物に
ならなくてprintfデバッグ中心になる理由。 >>465
[追加2]
・リンカをVC++のlink.exeに頼っている。
・ツール類がVC++に比べてとても貧弱(赤ちゃんのおもちゃ)。
・unsafeを使わないととても面倒なことが多い。
・C++では、newとdelete以外にはコンパイラが独自提供しているもの(Hooks)
がないが、Rustでは大量に有る。例えば、Box<T>はソースがあるようにみえて
実質はコンパイラ提供のものなので途中でソースがなくなっている。
・C++を含めた多くの言語では、コードの位置の任意の一部を切り取って関数化する
ことは平易に機械的に(一般的に)できるが、Rustだと一般的には出来ない。
なぜならRustのコードは、その文脈においてのみ有効なコードに過ぎないからである。
文脈に応じて書き換えなければボローチェッカに文句を言われてコンパイルが通らない
から。 >>466
[追加3]
・「Rustは独断的な言語です。それは良いことも悪いこともあります。
あなたがたまたまその意見に同意するならそれは良いことです、
さもなければそれは信じられないほど迷惑です。」 「システムタイプのプロジェクトでやらなければならないことの多くは、Rustでは実行できず、安全でないコードが必要になります。そしてもちろん、使用する基盤となるモジュールの多くには、安全でないコードが含まれています。したがって、ある意味で、メモリの安全性の約束は実際には真実ではありません。それらのいずれかが、現在または将来、コードの他の場所で量子力学的問題を引き起こす可能性のあるメモリの問題を抱えている可能性があります。もちろん、それを実行する可能性のあるコードの量を大幅に削減しますが、それでもかなりの量があります。」
「RustがC ++の句読点の爆発を起こし、さらに悪化させたように感じます。コードのコンパクトさは、読みやすさに比べてそれほど価値があるとは思いません。Rustはシステムの言語であり、SPAフレームワークではありません。それを速くすることは目標ではありません、それを正しくすることは目標です、そしてそれはそれを何年にもわたって書くよりもそれを読んで編集することに非常に多くの時間を費やすことを含みます。」
「コンパイラには、C ++よりも多くのライブラリへのフックがあります。大規模で完全にコヒーレントなシステムの構築に関心のある私たちの中には、それを困難にしている人もいます。C ++では、基本的に新しく削除され、他のすべては完全に自分で行うことができます。」
「Rustは、例外や継承など、何十年にもわたる成功を無視していると感じています。私は自分が書いているコードを見て、ほとんどすべての呼び出しが?で終わる場所で、手作業で効果的に例外を実行しています。そして、すべてのメソッドは、自動的に伝播される可能性のあるエラーを手動で返す必要があります。」
「Rustの安全規則は、より安全なコードを作成しようとする試みと戦う場合があります。」 僕は絶対にミスはしませんって言って全部unsafeで包もうぜ >>464
> ・長い歴史で実績の有るクラスの継承や例外機構が使えない言語設計。
クラスの継承や例外機構は長い社会実験の末クソだったって結論出たろ。
だからGoだってわざわざ外してる。
C++にあるものを「実装できない」訳がないよな。わざわざ外してんだよ。 読んだのか、凄いなw
しかし、スルー検定3級不合格です CやC++の批判で同じようにredditでコメント集めたらこんなもんじゃ済まないだろ c++と結局同じ道を辿ってるというところが一番愚かな点。
rust覚える早道が結局c/c++勉強することっていう。 >>474
低IQだから最初の文と次の文の間の論理が読みとれないので
申し訳ないですがもう少し丁寧に説明して頂けないでしょうか FFIのデファクトとしてのC ABIはしょうがないけど
C++とか一切触れる必要ないだろ レディットの負け犬に反論する必要なくない
賢さでいったらポメラニアンと同じくらいの連中なのに 所有権の重要さを実感するのは結局c++やってたやつだけだろ。
本当に一切c++触らないでrustだけで覚えたとかいう奴はいないわ。
いてもまともなコードは書けないだろう。 >>475
俺はそいつじゃないが、二文は繋がってない独立した文。 >>477
redditみたいなアメリカ最大の一般的な掲示板に書き込む人が皆、負け犬なんて
分けはない。
むしろSourceForgeみたいなところは、プログラミング関連の掲示板だから、
プライドだけが高くて力が無い人が集まることも有り得て、ずっと偏りが
あるため、負け犬率が高い可能性がありそこの好きな言語ランキング
なんて信用なら無い。 はっきいり言って、2ch/5chでも人が大量に来る一般的な板は平均程度の
知的レベルはあるが、この板みたいな技術系の板は、なぜか平均より低い人が
集まりがち。
なぜならリアルで認めてもらえない人がストレスのはけ口のようにして
書いてくる率が高いから。
その意味でSourceForgeは一般人より馬鹿が集まり易く、redditは一般人と
同程度のレベルがある。
2ch/5chもニュース意が見たいなのは一般人と同じくらいの知的水準だが
プログラム技術板は一般人よりも何故か劣っている。 githubも負け犬や雑魚が集まり易い。
有名な凄腕シェアウェア作家などはそんなとこに投稿せずに稼いでいる。
自分の腕ひとつでは稼げない人が、最後の手段としてなんとか名声を得てサラリーマン
として雇ってもらうためにgithubに投稿する傾向がある。
SourceForgeも同様。 >>483
サンプル数1(自分自身)で100%という調査結果があるんだろう >>486
サンプル数1(自分自身)で100%という調査結果があるんだろう >>488
D言語でいう契約を静的に検証できるみたいな感じかな? いいね OSS界隈で盛り上がる感じはしないけど
自動車とかはそっちのほうが見込みありそう Vecのget()メソッドがi32とかも受け取ってくれればよかったのにとよく思う
結局、負方面については自分でインデックス内か検証しないといけないし extension traitとかnewtypeで拡張すればいいんでは?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1b575c52e97e24c3ae345e945ec7dbbd はえ〜ありがとうございます!
これ標準ライブラリに採用してほしい(我儘) たとえばこのように書いたときに
fn zero_bytes<T :Sized>() -> [u8; std::mem::size_of::<T>()] {
[0u8; std::mem::size_of::<T>()]
}
エラーとして
the size for values of type `T` cannot be known at compilation time
となってしまいます。
型の大きさに依存した配列を生成するには (実際にはコンパイル時に確定するはずでも)
Vec などを利用するしか仕方がないのでしょうか? >>498
配列の要素数はconstじゃないとだめだからジェネリックには今のところできないみたい
どこかで型を書かないと
const SIZE: usize = std::mem::size_of::<i32>();
let foo = [0u8; SIZE];
https://github.com/rust-lang/rust/issues/43408 const fn, lazy_static のあたりは他の言語やってた人にはわかりづらいよな コンパイル時計算は最近の言語じゃ普通だけどな。
コンパイル時リフレクション使える言語も増えたし。
>>498
ttps://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e09bdfe4323f597481eae11421777cc3
ttps://rust-lang.github.io/rfcs/2000-const-generics.html
ttps://github.com/rust-lang/rust/issues/44580
一時間前にマージされたばかりで1.51.0のマイルストーン完了したからそのうちnightlyに来る。
ttps://github.com/rust-lang/rust/pull/79135
edition 2021には間に合うんじゃないの? Java では、class Foo{ Bar bar; } で済むところが、Rustでは以下の様な選択肢に悩まされる。
struct Foo { bar: Bar }
struct Foo<'a> { bar: &'a Bar }
struct Foo<'a> { bar: &'a mut Bar }
struct Foo { bar: Box<Bar> }
struct Foo { bar: Rc<Bar> }
struct Foo { bar: Arc<Bar> }
そして特に、'aの部分やBox, Rc, Arcの取り扱いやRcとArcの違いなどに悩まされる
ことになる。
これに加えて実践的にはOption, RefCellなどを何重にも組み合わせて使うことが必要となり
正しく理解するのはC++より遙かに難しい。 >>502
ちなみに、plain Cの場合、
struct Foo { struct Bar *bar; }; // (1)
で済む。C++の場合、もちろんこれでもいけるが、
class Foo { Bar *bar; }; // (2)
1つでも特に問題ない。
uniqu_ptr<Bar>やshared_ptr<Bar>
も使えるが (2)で出来ないことは特に無いし、難しくも無く
Javaのclass Foo{ Bar bar; }
と使い勝手も余り変わらない。
違うのはbarが不要になった時に自分で deleteするだけで、
多くの場合、
class Foo {
Bar *bar;
Foo() { bar = NULL; }
~Foo() { delete bar; }
};
と書けばよいだけで、これはパターンなので丸覚えでも良いし、意味の理解も
難しくも無く、悩むことも無い。
それに比べればRustが如何に複雑なことか。 [補足]
C++の場合も、
class Foo { Bar *bar; }; // (1)
class Foo { unique_ptr<Bar> bar; }; // (2)
class Foo { shared_ptr<Bar> bar; }; // (3)
の選択肢は有るには有るが、常に(1)を使ってもコンパイルエラーに悩まされる
事はないし、できないこともなく、特に危険でもない。
ところがRustの場合、状況に応じて>>502のどれか一つしか選択できない
ことが多く、柔軟性に乏しい。
プログラムに僅かな変更があったときに、C++の場合、(1)なら修正が全く
必要がないが、Rustの場合は>>502のうちのどれかからどれかに修正しなくては
ならないことが多い。 https://matklad.github.io/2020/09/20/why-not-rust.html
「Rust lacks an official specification. The reference is a work in progress,
and does not yet document all the fine implementation details.」
Rustは公式の使用が欠如している。
リファレンスマニュアルの作成は発展途上中(作成中、作業中、進展中)で、
しっかりした実装の詳細を全てドキュメント化してはいない。
Rustのコンパイル時間がとても長いことを直後に指摘した上で、
「A program written in a slower to run but faster to compile programming
language can be faster to run because the programmer
will have more time to optimize!」
実行速度が遅いがコンパイルが速い言語で書かれたプログラムは、
実際には速く実行できるようになる。
なぜなら、プログラマが最適化する時間をより沢山得ることが出来るためだ。 現実のプログラムでは、CやC++とRustのプログラムを連携しなければならない
ということと指摘した上で、Cargoがそれを難しくしているかも知れないことを
指摘している:
「One specific gotcha is that Cargo’s opinionated world view
(which is a blessing for pure Rust projects) might make
it harder to integrate with a bigger build system.」
具体的には、Cargo主張する世界観(これは純粋なRustプロジェクトにとっては
幸いなことです)が、より大きなビルドシステムとの統合を
難しくしているかもしれないということです。 「First, there’s no definition of Rust memory model, so it is impossible to
formally check if a given unsafe block is valid or not. There’s informal
definition of “things rustc does or might rely on” and in in-progress
runtime verifier, but the actual model is in flux. So there might be some
unsafe code somewhere which works OK in practice today, might be
declared invalid tomorrow, and broken by a new compiler optimization
next year.」
第一に、Rustのメモリモデルの定義がないので、与えられた安全でないブロック
が有効かどうかを正式にチェックすることができません。非公式な定義として、
"rustc が行う、または依存しているかもしれないこと "と、進行中のランタイム
ベリファイアがありますが、実際のモデルは流動的です。つまり、どこかに安全
でないコードがあるかもしれませんが、今日は問題なく動作していても、明日
には無効と宣言され、来年の新しいコンパイラの最適化で壊れてしまうかも
しれません。 Second, there’s also an observation that unsafe blocks are not, in fact, modular.
Sufficiently powerful unsafe blocks can, in effect, extend the language. Two such
extensions might be fine in isolation, but lead to undefined behavior if used
simultaneously: Observational equivalence and unsafe code.
第二に、安全でないブロックは実際にはモジュール化されていないという観察もあります。
十分に強力な安全でないブロックは、事実上、言語を拡張することができます。
そのような2つの拡張は単独では問題ないかもしれませんが、同時に使用されると定義
されていない動作になります。観測的等価性と安全でないコードです。
Finally, there are outright bugs in the compiler.
最後に、コンパイラには明らかなバグがあります。
https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3A%22I-unsound+%F0%9F%92%A5%22 まあ大体その通りだわな。matkladはわかりやすい文章書くわ。 スマートポインタ絶対に使いたくない理由はよくわからんが
rustでも生ポインタ使えばよいのでは
コンパイル時間についてはcraneliftと差分コンパイルの進化に期待かな
その他の議論については影響は限定的だし
影響を受けない領域でrustを使えば良いのでは
議論の俎上には挙がっているし徐々に改善されていくでしょう >>510
>その他の議論については影響は限定的だし
ところがC/C++が担ってきた領域ではそれが大問題になることが多いので
RustはC/C++の代替には成りえない。
>議論の俎上には挙がっているし徐々に改善されていくでしょう
少子化も日本の経済衰退も非常に何十年間も議論の俎上に上がっている
のに改善されていく気配は全く無いことからも分かる様に、
そんなことは一般的には成り立たない。 >>510
>rustでも生ポインタ使えばよいのでは
Rustのsafeモードでは生ポインタは使えないんだが。 >>512
実際に安全ではないので unsafe なのはあたりまえだが。
C++ のように常に危険なほうが良いなら C++ を使ってろよ。 >>513
Rustはメモリーマネジメントの仕様がちゃんと公開されて無いので
C++よりずっと危険。 >実行速度が遅いがコンパイルが速い言語で書かれたプログラムは、
>実際には速く実行できるようになる。
最近この苦情よく聞くんだけどどんなもんなの
コンパイル時間のボトルネックなんて
考える時間に比べたらたいしたことなくない
何十分もかからんだろ CIとかでめちゃくちゃ時間かかるのはRustの醍醐味 >>515
今のRustコンパイラはコア数で良くスケールするので
開発用の32コアマシンなら快適だけど、古いノートPCだと辛い、みたいなことはあるな
Actixみたいに大量の依存関係を要求するやつ+しょぼいシングルコアなら数十分かかるかもね 個人的にはクレート単体で遅いと思ったことはなくて、体感では数万行のコードでもgccより速いかな、という感じ
なので遅い要因はほぼ依存関係の多さだと思っている
C++とかだと特定のディストリビューションの特定のバージョンでコンパイルエラー、みたいな地獄のデバッグが待っているので、それを回避するコストとしては十分安いと思うけど 今の方法だとまだ依存crateのコンパイル待ちになるのにスケールする?
>>518に尽きる >>521
もちろん完全に直列な依存関係はスケールしないよ
もしそういうクレートがあるなら分割すれば改善するかもしれないし
具体的に挙げて欲しい >>520
>個人的にはクレート単体で遅いと思ったことはなくて、体感では数万行のコードでもgccより速いかな、という感じ
C言語のコンパイル意が遅くなるのは、Win32のヘッダファイルの巨大さが原因
であることが多い。
それが50MB位有ったりして、ヘッダファイルだけで数万行から数10万行くらいあったりする。
そのパースが遅い。
なので、VC++では precompiled header を使っている。 ライブラリの依存関係を自動で解決するエコシステムがあると
依存関係が巨大になりがちっていうのは
Haskell や JavaScript でもよく聞くけどな。
まあ自分でそのライブラリ群を書く手間、
既存のものを使うにしても導入の仕方を調べる手間に比べたら
多少の時間はかかっても自動でやってくれるほうがマシではあるし、
度を越したときは個別に改善するしか仕方がないんだろう。 依存関係のコンパイルは初回しかやらないんだから多少遅くても気にはならない
CIの場合はtargetディレクトリキャッシュすれば良いし
rust-analyzerの起動時間がちょっと気になるくらい >>522
昔より増えたapiとimplを分離したクレートは
自分のプロジェクト->api->impl->implが依存するcrate(s)->...
と直列に依存してる。log,slog,serde,thiserror,webrender(etc.)
それに直列に依存するかどうかよりcargoもrustcのフロントエンドもまだ並列化対応が部分的でコンパイル単位の粒度が大きいのが並列ビルドの妨げになるでしょ。
>>526
CIはたしかにキャッシュが効けばいいけど、アナライザの話なら初回しかやらないことはないよ。
アナライザの場合は解析結果が無効になるたびに起きる。
intellij rustはプロジェクト開くたびにやってるし。
JDTみたいにon the fly analyzeするとソースコード変更するたびに解析するから依存グラフは使い回せても他は都度、解析する必要がある。 >>527
言葉足らずですまん
(解析結果をメモリ上にしか持たない設計だから起動時に解析を全部やり直す)rust-analyzerの起動時間が気になるくらい(がコンパイル時間に関して気になる点)
と言いたかった #![feature(min_const_generics)]だけじゃなく#![feature(const_generics)]も2021に入って欲しいな 全く話は変わるけど、メモリ不足で Box::new に失敗したら、panicが起きて
プログラムがそこで停止するだけ? >>530
仮にそうだとすると、Cのmalloc()やC++のnew TYPEに比べるとエラー処理は
省ける反面、エラー処理を書きたくてもかけないね。
まあ、滅多に起きないので書いてもしょうがないけれども。 *C++
TYPE *ptr = new TYPE; //メモリ不足の場合ptrにはNULLが返される。
*Java
TYPE obj = new TYPE; //メモリ不足の場合例外がthrowされる。
*Rust
Box<T> obj = Box<T>::new(T()); //メモリ不足の場合panicが生じアプリがダウンする。
Rustは、高度な安全性を要する分野や組み込みでは困るかも。
それに記述が長い。 C++のnewはメモリ不足のとき通常は例外が送出されるぞ
メモリ不足でnullptrを返すにはnew(nothrow)にしないといけない >>533
昔、
TYPE *ptr;
if ( (ptr = new TYPE) == NULL ) {
printf( "Memory allocation erro has occured.\n" );
}
みたいに書いていたことがあるけど、これは昔のC++でも間違っていたのだろうか? Javaは、例外をthrowする関数を呼び出した場合、必ずtryブロックで囲むか、
または、呼び出しもとの関数の宣言の最後にthrow/throws属性をつけるかしないと
いけないんだけど、なぜかnew演算子の場合だけはこの規則の例外で、
tryブロックで囲むこともthrow/throws属性を付ける必要も無いらしい。
ただし、tryブロックで囲んでcatch文でOutOfMemoryErrorという例外を
捉えることは出来るらしい。
意外と良く考えられていて、便利そう。 知識が無くてもそれが使いにくいことが分かる人もいれば、
知識があってもそれが使いにくいことが分からない人もいる。
その差はイマジネーションや経験や頭の良さの差。 知識も経験もイマジネーションも頭の良さもない
お前さんどうすんの? 20年以上前?のC++だとNULLが返ってきてたみたいだな
C++98の頃には例外が投げられてる プラットフォームにもよるのでは
panic=abort
しかない環境もある かなり初歩的な質問で申し訳ないんだけど、例えばHashMapをイテレータで舐めてるときに内部でそのHashMapを更新したいときはどうするのがベストなの?
例えば次のようなケースではどうすれば……
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f6c554ab761450881f28e48faa55bf8c
use std::collections::HashMap;
fn main() {
let mut map: HashMap<_, _> = HashMap::new();
for i in -5..=5 {
map.insert(i, i);
}
for (key, value) in map.iter() {
if *value == 0 {
continue;
}
if let Some(another_value) = map.get_mut(&(-key)) {
// keyの絶対値が同じものを処理して、処理済みにする気持ち
*another_value = 0;
}
}
} >>543
map.iter() を map.iter().cloned().collect::<Vec<_>>() にする keyの絶対値が同じものでgroupingしてからイテレート rust的にはそういうことしないのがベストじゃない
俺だったらキーだけ取り出してループさせる >>544-546
ありがとう!
しかしRust的には褒められたやり方じゃないんだね
LL言語脳から切り替えないといけないなあ 逆に-keyで絶対値にする言語とかあんの?
Rustではkey.abs()だぞ
> keyの絶対値が同じものでgroupingしてからイテレート
ソース見る限り元キーはそのままで{-1: 0, 1: 0}みたいにしたそうだからグルーピングでは絶対値にキー統一されるからダメだね >>543
イテレータを回してるときに内部でそのcollectionをいじくる一般的な方法を聞きたかっただけで、そのコードはただ説明のためのモックなのでコードの妥当性とかはどうか気にしないでください…… これは個人的な解釈だけど、ループ中にコレクションをイジるのを許可すると要素の追加削除も許可されるので、動作が想定しにくいから言語に関わらずやるべきじゃないと思う 有名なアルゴリズムでも破壊的に処理を進める物は少なくないから
それらをリソースを押さえたままより安全に実装するかという問題はある 単純に破壊的操作とイテレータの組み合わせが良くないんだと思うけどね
基本的なアルゴリズムの実装でならC++でも大抵インデックスアクセスするし 絶対値で比較されるようなkeyの型を用意してBtreeMapにぶちこんでiter_mut()すれば
絶対値が同じキー同士は連続して現れるからうまいことやればやりたいことはできるのでは
コード複雑になりそうだけど >>550
C++狂い「安全性よりも論理的、数学的に正しいかが重要」 Rustで大量の敵が同時に出現する2Dゲームを作ろうと考えています。
Amethyst、ggez、Bevyの中で最もおすすめのゲームエンジンはどれでしょうか? >>552
まあ通常そういう場合はint値でモロにインデックスアクセスするわな。
これがrustとは全く馴染まない。 single writer or multiple readerのモデルに沿うようなロジックに変換するか
interior mutabilityを使うかのどちらか >>555
個人的にはAmethyst。
なぜなら俺が個人的にECSアーキテクチャが大好きだから。
小さなプロジェクトに向かないとか言われるけど知らないそんなの。 RustでTDみたいなブラウザゲー作った猛者おりゅ? なんでこんなゴミを100M単位でボコボコダウンロードせなならんのや
ゴミ 評価順序のルールがよくわからないんですが、
タプル生成のときの呼出し順序って保証がありますか?
つまり
(foo(), bar())
みたいに書いたときに foo が常に先に呼ばれることは保証されますか? 保証されてるんじゃない?
でも呼び出し順が重要なら行を分けて書いてからtupleに入れたほうがいいような気もする
The meaning of each kind of expression dictates several things:
・Whether or not to evaluate the sub-expressions when evaluating the expression
・The order in which to evaluate the sub-expressions
・How to combine the sub-expressions' values to obtain the value of the expression
https://doc.rust-lang.org/reference/expressions.html >>565-566
ありがとうございます。
無学なので少し書き方が分かりやすくなっても英語だとしんどい……。 ファイル (またはネットワーク) から得られる所定の書式のレコードの繰り返しを
イテレータとして抽象化したいと考えました。
(ちなみにレコードの繰り返しの前にレコードの個数を含むヘッダもあります。)
しかし IO はエラーの可能性があります。
書式の仕様に違反する入力になっている可能性もあります。
イテレータが返す型を Option<Result<要素の型,エラーの型>> としてしまうと
エラーの時点で終端という扱いにならないので様々なメソッドと組み合わせ難いですし、
Result を挟まないとエラーの内容を返せないのでハンドリングしづらいです。
何か綺麗にやれるイディオムのようなものがあったりしませんか? エラーの時点で終端にするかどうかは呼び出し側が決めることじゃない?
Option<Result<T, E>>もResult<Option<T>, E>もイディオムとしてよく使われてる >>569
出来るか出来ないかで言えば出来るし好きにすれば良い話ではあるんですが、
標準で良いされている様々なメソッド (たとえば map のような基本的なメソッドさえ!)
と「組み合わせ難い」ということが綺麗じゃないなぁという気持ちなんですが、
そこらへんの不格好さは許容するしかない雰囲気ということでしょうか?
(通常の終端に到達するのとは別に) 中断を表現する方法があって
中断の理由を伝播するのに便利な語彙を詰め込んだクレートがあったりすると
助かるんですが。 >>570
公式にあるイディオムっぽいのはこれとか。
https://doc.rust-lang.org/rust-by-example/error/iter_result.html
クレートは探すと色々見つかるけど、結局「便利な」ってのが人それぞれだし、あまり流行ってる感じはしないな。
むしろその中断表現をうまくやるアイデアがあるなら自分で作ったほうがいいのでは。 >>570
組み合わせ難いと言ってる内容をコードで示してくれないとなんとも イテレータとして抽象化したいってどういう意味なの
Iteratorをimplするってことなのかしら >>573
ここでいう「イテレータとして」というのは std::iter::Iterator に限るわけではなく、
繰り返しを表現する何らかの型定義と思ってください。
適当なクレートがあるならそれでいいですし、考え方だけでもいいです。
欲しい機能をあらためてまとめると
・ 繰り返しに (終端に到達する以外の) 中断の方法が用意されている
・ 中断したときに中断の理由 (エラー型の値) を伝える方法がある
なのですが、
std::iter::Iterator だと next が返す Option<Result<T, E>> でエラーのときに
「中断」しようとすると for 文の中で break する書き方くらいしか思いつかず、
自分で便利なものを作ろうにもどう作れば便利になるのかも
想像がつかないのです。 >>574
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=aaf882f54a7b6330ee6ad2106be92717
こんな感じでscan使えばNoneを返したところで
イテレーションを中断できるしErrの値も列挙できる 中断するだけなら take_while 使うという手もある 俺もtake_whileを思い浮かべたけど関数を作るわけじゃないんでしょ
ゴールがいまいちみえないからイメージでいいのでコードで用件を示してほしい 単にエラー返して中断したいだけならResultにcollectしたりtry_for_eachで消費すればいいよ
イテレータアダプターとしてエラーも含めて列挙しつつ次につなげたいなら>>575が書いてるscanやtake_while系
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=113dcf689b4d941c89e714ebb1414958 AsRefトレイト使ってenumから&str返すのっておかしい?
Display実装で文字返してたらアロケートされるからAsRef使おうと思ってるんだけど >>579
AsRef に拘らず独立した as_str 用意した方が良いと思う AsPath が AsRef<Path> になった過去もあるから汎用性持たしてas_str実装するよりAsRefで実装する方がいいといいと思うけど他の人はどう思う? 自分で使う、as_str
ライブラリとして他で使われる、AsRef >>580
学習難度はまず低級言語と高級言語両方の利点欠点を理解しないと良さが理解出来ないからねえ…
設計思想からして中上級者向けだから仕方ないかも 単に学習難易度が高いだけでなく、学習が済んだ後もこの言語はめんどくさいが、
C++よりもむしろ。 >>582
AsRefはIntoOwnedと対になっていて str<->String Path<->PathBuf みたいな ref/owned 関係にあるもの同士の変換に使うものだと思う
enum -> &str はそういう関係にはないので微妙に思う >>586
風俗で事が済んだ後で説教始めるオッサンみたい C++とRustで難しさめんどくささの方向性違うしな
好みの範疇だと思ってる Rustのめんどくさいところはダントツでクレート関係だよな
標準で入ってないかつ、細かすぎるからコンパイル糞長いし、APIの仕様が統一されてないからドキュメント見ないと話にならんとこ
しかもクレートによっちゃライフタイム絡ませてきてめちゃくちゃになるし
C++はとにかく言語仕様のいらない豊富さが嫌気さす >>590
traitのおかげで他と比べるとAPIの統一性は達成されてるようにおもう クレートいいと思うけどな
標準ライブラリに入れると破壊的変更できなくなるけどクレートなら古いバージョン使うことも出来るから
気兼ねなくライブラリを進化させることが出来る pure-Rustのクレートなら今のところ確実にコンパイルは通るしな。
C++だとGitHubから拾ってきたライブラリが手元でコンパイル通るかどうか半々って感じで厳しい。
マイナーなディストリビューションのせいではあるけど、全部Ubuntuに統一というわけにもいかんしなぁ。 struct A;
struct A();
これとこれが定義できる理由ってなんかある?
struct A {};
だけで済むし、記述バラバラになるから統一したいんだけど Rustが一番めんどくさいのはメモリ管理だな。
というよりメモリ管理の事ばかり気にしてプログラムしなくてはならない。
plain CやC++ではそこまで気にしなくて良い。 結局メモリを気にする言語にへんな暗黙性を入れるのは失敗ってことだな。 Rust で書いたツールにドキュメントを付けようとしています。
ライブラリのドキュメントではなくツールとしての使い方の詳細で、
readme に書くには大きすぎるような文章です。
cargo.toml では package.documentation でドキュメントの場所を URL で
示すことは出来るようですが、パッケージ内にドキュメントを一緒に入れておいて
cargo install で適当なところにインストールするようなことは出来ないのでしょうか?
あるいは cargo の直接の管理下には入れられないにしても
なんらかの習慣があったりしますか? manみたいにドキュメントインストールする方法は知らないな。
ローカルにインストールしなくてもリポジトリのwikiあたりに使い方書いておいてそれ見てねでいいんじゃないかとおもうけど。 ビルドスクリプト使ってenv::var("OUT_DIR”)で取得できるパスにファイル出力してるのが多いみたい なるほど。 そういうやり方もあるんですね。
でもドキュメントを各環境で適切な場所に
インストールするのは結局は手作業ということになりそうですね。
そういうことなら無理に自動化するのは諦めて
必要ならこのディレクトリで mdbook コマンドを実行してねみたいな感じにした方がかえって楽かな…… cargo installでrustバイナリ以外をインストールするオフィシャルの方法は長年用意されてないから別の手段で頑張るしかない
https://github.com/rust-lang/cargo/issues/2729 fn num() -> usize {
10.pow(9)
}
この定数はなぜ推論でusizeにならないんですか? なんでいちいちゴミをワサワサDLしなきゃならねーんだよゴミ言語 DustじゃなくRustだからゴミじゃなくてサビ言語だよ その2つは別のもの
どっちも存在する
&strはstring sliceのborrow
&StringはStringのborrow >>613
同一だと思ってたけど違うの??
&strを要求する関数とかメソッドに&String渡しても動くもんだからてっきり &strはStringの一部か全部へ参照 rust的にはスライスへの参照
&string[1..3] こういうこと
引数を&StringにするのStringの参照しか渡せないが、&strにすればStringの一部や””で囲った&strも渡せる >>614
引数として&strをとるメソッドや関数に&Stringは渡せないんじゃなかったっけ
self の場合の話? >>618
二つ目の例だけ記憶してて勘違いしてたみたい。ありがとう
>>619
rustは暗黙変換かなり少ないからマシな方だと思う
メソッドのselfの暗黙変換はないとつらいかと Option::filterのResult版って無いのかな? >>621
条件に合致しない場合は何を返して欲しいの? >>622
引数で渡したエラー値をErrにくるんで返してほしい >>623
うん、それが最適でしたね
もともとTと&T -> boolからOption<T>を構築してたコードがあってSome(t).filter(|t| !t.is_hoge())ってしてたんだけど
それをResultに変えようとしたらif式で数行増えちゃって
ちょうど対応するようなのって無いのかな?って思って質問した次第でした それはok_orかok_or_elseで変換すればいいだけじゃなくて? Rustの良さが実感できるのは長大なコードをチーム開発するときなのかな
小さいプロジェクトならRustは
・生ポインタ使わない
・できる限りSTLを使う
・const、moveをデフォルトで使う
ことにしたC++に敵わないような
C++の方が柔軟だしず〜っと短く書けるし あ、標準の機能とかイディオムを巧みに使えばC++並みに短く書けるよ、というのがあったら教えてください どちらかというとC++の方が長くない?
ヘッダとソースの重複とかイテレータが冗長とかshared_ptrが長いとか。
あと小さいプロジェクトだとビルド環境構築の手間が
相対的に大きくなるからC++はつらいな。 あとなるべくconstにしたいのに多用すると結構長い RustスレなのでRustの味方をすれば良いと思うが、>>629はあまりにも言いがかりだろう
> ヘッダとソースの重複
重複するコードを書かなければならないことなどない
> イテレータが冗長
今どきautoせずにイテレータを書くことはない
> shared_ptrが長いとか
これは確かに >>631
テンプレートでなければ関数プロトタイプと実装で同じこと書くと思うんだけど最近は違うんだっけ?
あとイテレータはbegin/endのこと。これも書かなくて良くなったりしてる? >>632
特殊化が必要なら当然特殊化するし、プロトタイプしか与えられてない関数は当然中身を他の場所で実装しなければならない
が、いずれもヘッダその他で書いてあるのと同じことを繰り返し書くという意味ではない
「引数と返り値をプロトタイプと実装で二度書くじゃないか」と主張してるのか?
だとしたら、「Rustのtraitとimplは同じことの繰り返しだ」と同レベルのデタラメだ
> あとイテレータはbegin/endのこと
範囲for文はあるので、コンテナを走査する時にはbegin()もend()も書く必要はない
が、begin()やend()の指すイテレータが必要なら当然書く必要がある
しかしこれより簡潔な表現方法があるか? >>633
いや、Rustのtraitとimplも同じことの繰り返しだと思うが。
もちろんそれぞれに意味があるのは分かるが、今話題になってるのは長いかどうかなので、単に長いのでは?ということ。
begin/endは言われてみれば確かにそんなに長くもないな。 そういえばRustだとderiveで導出できるようなのを
手で書かないといけないのも面倒だと思ってたけど
それも最近のC++だと便利になってるのかな? >>634
〜〜〜〜〜ッッ!!?!!????
型を示すだけぞ???
どういう理屈で「どちらかというとC++の方が長い」???
「プロトタイプ」なる仕様が冗長だと思ってるということか?
だとしてもどこがどうRustより長い?
traitとimplが同じことの繰り返しに見えるなら尚更 ゆうてID:tj1CufyMがもの知らん過ぎるよ
刃牙クンが正しい >>627 がどういうところでrustを冗長に感じたのかが分からないと身のある議論にならないのではないか let v2 = v.iter().take_while(pred).collect::<Vec<_>>();
auto iter_end = std::find_if_not(v.cbegin(), v.cend(), pred);
auto v2 = std::vector<Hoge>(v.cbegin(), iter_end); Rust言語を推進する「Rust Foundation」設立。AWS、Google、マイクロソフト、モジラ、ファーウェイらが設立メンバー
https://www.publickey1.jp/blog/21/rustrust_foundationawsgoogle.html >>646
無難なのは tokio だが、言語としては非同期ランタイムを固定しないという明確な指針がある以上は
使い分けしなさいということになると思う。 traitとimplが同じことの繰り返しは流石にキテレツ過ぎてワロタ
こういう基本的な言語仕様も分かってない人にとってRust使うメリットってあるのかな
「どっちが短く書けるか」については、流石にC++じゃないかな
良くも悪くも自由だし、短さだけを追求したクソコードも作れる
一方でRustも一応エルゴノミクスを掲げてはいるし、冗長さは感じない
C++が短くでき過ぎる、って言い方が正しいとおも >>642
林檎やfacebookの参入、ゲームやスマホでの導入例が出てくればこれはかなりの地位を占めるな コードを短くできるなんてどうでもいいことに囚われて半端になってる印象。 Firefoxでは160,000行のC ++コードを85,000行のRustコードに置き換えたと言ってる いやーRust難しくないっすか…
3回くらい入門したけどrustlingsのiterあたりでつらくなってくる
アホは他の優しい最新言語やったほうがいいんですかねぇ でもRustのコンパイル基盤のLLVMはいつまで経ってもC++製のまんまだよね
書き直さなきゃC++の牙城は壊せんで craneliftがあるじゃん
デバッグビルド向けだけど コンパイラはrust自身で作られてるからそのうちそうなるんじゃね? >>658
Appleは重要なパトロンではあるけど関心はApple以外誰も興味無い
キメラ言語のObjective-Cを守る一点だけだろ >>657
というかC++をちゃんと使いこなしている人は、Rustが便利だとは思えない人が多い
のでRust化する動機が無い。 >>662
>>627てこと?
> 小さいプロジェクトならRustは
> ・生ポインタ使わない
> ・できる限りSTLを使う
> ・const、moveをデフォルトで使う
> ことにしたC++に敵わないような
> C++の方が柔軟だしず〜っと短く書けるし >>663
むしろ、STLがクソすぎるのがC++が嫌われる原因。
C++は、STLを使わずに独自templateライブラリを使うのが便利。 >>664
「使いこなす」がレベチ過ぎてワロシ
コンテナとアルゴに関しては俺もSTL使う方が良いと思ってたわ
vector<bool>とか、難のある仕様があるのは理解してたがそういうのに個別に対処すれば十分だろうと
リーナスとかもSTLが大ッ嫌いだという記事をよく見るが、具体的にどこを毛嫌いしてるのか俺は理解していない そりゃOSレベルで見たらメモリの使い方がラップされるようなライブラリは使わんだろ。
馬鹿でもわかる話だと思ってたがそうでもないのか。 むしろ C++ のつらさを知ってないと Rust の良さは (悪さもだが) わからんだろ。 >>667
それ言ったらC++のCじゃない部分は全部ダメじゃね >>669
そうだよ
「OSを実装するためには」という条件ではね >>669
STLはCの良さを台無しにするような傾向がある。
C++の言語仕様自体は適切に使えばそのようなことはない。 >>672
> STLはCの良さを台無しにするような傾向がある。
これは観念的な話?
パフォーマンス的には、もちろん不要なコピー等は避けるという前提のもとで、同じなのかなって思ってたんだけど
> C++の言語仕様自体は適切に使えばそのようなことはない。
適切というのは、C with class として使えば、ということ? >>672
STL というものは C++ の中にはない。 C++ の標準ライブラリは C 的な良さを殺さないように配慮しまくってるから
抽象化層で抽象化しきれずにイビツになってるんで、
出来が良いとは思わんが C の良さを台無しにしてるとは思わんな。 >>675
そう思ってるならあなたも設計者の頭の出来も馬鹿。 >>662
MozillaもGoogleもMSもC++を使いこなせないからRustを支援してるって主張か? >>678
Mozillaなんか独占禁止法違反を誤魔化すためのGoogleの下請けに過ぎないので
レベルの高いプログラマはもはやいないし、MSやGoogleは巨大すぎるので
できそこないのプログラマも多い。 >>679
なるほど、Mozillaのプログラマは全員レベル低いしGoogleやMSでrustに関わってる人も全員出来損ないという主張なのね ダニング=クルーガー効果
ダニング=クルーガー効果とは、能力の低い人物が自らの容姿や発言・行動などについて、
実際よりも高い評価を行ってしまう優越の錯覚(英語版)を生み出す認知バイアス。
この現象は、人間が自分自身の不適格性を認識すること(メタ認知)ができないことによって生じる。
1999年にこの効果を定義したコーネル大学のデイヴィッド・ダニング(英語版)とジャスティン・クルーガー(英語版)は、
「優越の錯覚を生み出す認知バイアスは、能力の高い人物の場合は外部(=他人)に対する過小評価に起因している。
一方で、能力の低い人物の場合は内部(=自身)に対する過大評価に起因している。」と述べている。 >>675
抽象化しきれてないというのは、実装の話?
それともインターフェースの話? >>685
インターフェイス (仕様) の話だけど実装の話でもある。
たとえば C++ では vector の大きさが変わったら (それの要素を指す) イテレータは一斉に無効になって
コンパイル時にも実行時にも捕捉されない (捕捉することを保証しない) のは
明らかに vector の実装の都合を想定していて、
仕様を満たす範囲で効率的に実装すれば (vector の) イテレータの実体はポインタ一個になる。
C++ の標準ライブラリは C で出来ること、 C の習慣の見栄えを変えているに過ぎないし、
そうなるようにデザインされている。
実装がどうなっているかが透けて見えるような仕様になっているという意味で抽象化がしきれていないと書いた。 >>687
ありがとうございます
為になります
でもそれは裏を返すと、パフォーマンス的にはCと同等の効率で実装されていると思って良いんですかね?
(ただしラップしていることのオーバーヘッドはある?) >>668
学術的な言語理解ならその通りだが、言語習得という意味では寧ろ逆ではないかと
C++の瘴気に毒された民は清浄の地には住めない体になってる >>689
完全に成功していると言い切れない部分はあるかもしれないけど、
実行時に処理すべきことが同じならクラスやらテンプレートやらでラップしても
C と C++ でほとんど差は付かないよ。
少なくとも現代的な処理系で最適化を有効にして比較した場合には。 >>690
それはどうだろう。
俺はアマチュアだがそれでも C++ を二十年以上触ってきた感覚で言えば
Rust はかなり良いという印象なので、 C++ のグダグダさに
うんざりしてる人は結構いるんじゃないか?
C++ の自由さを楽に感じている部分もあるんだが、結局はツギハギだからなぁ。
理念的な良し悪しを置くとしても長期にわたって機能を増やしていれば
一貫性のないところだっていっぱい出てくるのは仕方がないことで、
どこかで時代をリセットしてやり直す必要はあるんじゃないかと思う。
俺にとってはそれが Rust って感じ。 rustももう十分一貫性ないだろ。c++リセットしたい割に同じ道行ってるのがどうしようもねーなという印象。 >>694
一貫性が壊れてきてるというのはわかるよ。
でも、それを繰り返すもんだという諦めがあるから、
Rust がグダグダになりきったらまた新しい何かが登場するだろうと期待して今は Rust ってこと。
C++ の状況をなぞるならこれから 15 年か 20 年くらいはなんとかなるだろ。 それで十分だ。
>>695
以前のスレでも書いたような気がするが、
is_alphabetic の引数は self なのに is_ascii_alphabetic は &self だったりするとかみたいな
微妙な歴史的経緯がちょろちょろと見え隠れする。
個別に見れば重要ではないんだけど、
そういうどうでもいいことの積み重ねが全体としてのいびつさになる。
かといってそこらへんを綺麗に整理しつづけるために互換性を失うようでも
受け入れられなかっただろうというのもあるので、
そこらへんは本当にしゃーないんだわ。 エディションで定期的にリセットする仕組みが機能するかどうかは興味あるな
Rustで初めて挑戦する感じだから、良い感じに機能するのはさらに次世代の言語になるだろうけど >>687
>実装がどうなっているかが透けて見えるような仕様
私はむしろ、実装が透けて見えるのが王道だとおもっていたのですが、あなたのいう「抽象性」というのが私の感覚とは違うのかもしれませんね
抽象性を徹底して理解するためには、どんな勉強をすればいいのでしょうか? >>692
>C++ のグダグダさにうんざりしてる人は結構いるんじゃないか?
私はまだ経験が浅いのかもしれませんが、そんなに C++ がグダグダだとは思っていません
どういうところがグダグダなのか例示していただけるとありがたいです‥‥ >>698
抽象というのは、要は余計な要素をそぎ落とすという話なので考え方によっては
どこが余計なのかというのは変わりうるけども、仮に vector の本質を
「縮小・伸長可能な配列」であると考えるならば
・ 要素が隣り合う
・ 要素アクセスのコストのオーダーは O(1) である
といった性質は本質に付随する性質として受け入れられる。 でも、
・ 配列を伸ばしたらイテレータが無効になる
という仕様は
・ 配列の大きさを変えるのをメモリの確保しなおしで実現する
・ イテレータの実体はポインタ一個である
という実装上の理由 (を想定している) なので、抽象化の漏れだと思う。
イテレータをコンテナ (の参照) とインデックスの組で実装すれば回避可能なわけだし。
でも C++ の標準ライブラリでは C の価値観を以て抽象化よりも実行効率を優先するという選択をした。
繰り返すけど、これは何を本質とみなすかという見方によって変わりうるので、
考え方によって詳細は変わるかもしれないということには注意。
・ 対象は何である (ように見せている) か?
・ 対象がそう見せようとしている通りに使えるか?
・ その上で対象がそう見せかけようとする以外の部分 (実装の都合) を「忘れられる」か?
というのがライブラリが持つ抽象性。
カプセル化で大事なのは情報隠蔽だというのをどっかで読んだことくらいあるでしょ。
余計なことは見せないほうがいい。
んで、私 (>>687) にとっては vector のメモリ管理の都合は (少なくとも必要になるまでは)
忘れていたい余計なことだと思えるということ。 >>699
特にいびつさを生み出している例はヘッダファイルかな。
ソースファイル (.c) がひとつのモジュールとして機能して
ヘッダファイルがモジュールの外に向けたインターフェイスとして機能する
というのは C の世界ではまあまあ上手くいっているのだけど、
ヘッダファイルに定義を書くようになってから役割の境界が破綻してきた。
従来の C の世界では「定義はどこかのコンパイル単位に属す」という前提があったが、
ヘッダ内での実装 (テンプレートやインライン関数) ははっきりした所属がない。
テンプレートαがテンプレートβを使っていてソースファイルγでαを使いたければ
γ内からβも見えてしまうので隠蔽しきれない。 (カプセル化の破綻)
C++er にとってモジュール機能の導入が悲願のひとつと言われ続けていたのは、
ヘッダファイルという仕組みが理由になっている色々なグダグダの解消につながることが
期待されていたからだよ。
C++20 でとりあえずモジュールが導入されたけど色々な機能をモジュールを前提
にしたものに置き換えて古い仕組みがフェードアウトするまではまだまだグダグダする
だろうけどな。
ところでこれ以上は Rust スレで C++ の話を続けるとうっとうしがられるので、
質問があればこれ以降は C++ スレで。 板違いでしたらすみません。
カスタムSMGでリロードしても
弾が装填されません。
弾はピストル弾であってますよね?
バグですかね
よろしくお願いします 板違いでしたらすみません。
カスタムSMGでリロードしても弾が装填されません。
ちなみにピストル弾です。
バグですかね
よろしくお願いします。 鉄道やデジカメ、プログラム、ゲームの板のスレって
いつも無関係な話題で罵りあってるよね
これらの板って何か変な物を吸引するのだろうか pythonのモジュール作成者にもっとrustの利用が促進されればいい感じになりそうな気がする >>709
Rust 使えるなら Python 要らないだろ。 wasmはWebブラウザだけでなく、令和のJavaアプレットのように Write once, run anywhere を標語に
あらゆる目的で使われるようになるよ ちょっとしたやつでもファイル容量大きくなるからまだ無理
さらにいえばjsでもgpu使えるから並列計算ならそれ使えばいいし、wasmの用途は限られる
将来的に5gとかで通信速度上がったら使われるようになると思う 今、5GのEdge Computingがwasmの適用範囲として最も注目されている領域 >>700
>・ 配列を伸ばしたらイテレータが無効になる
>という仕様は
> ・ 配列の大きさを変えるのをメモリの確保しなおしで実現する
> ・ イテレータの実体はポインタ一個である
>という実装上の理由 (を想定している) なので、抽象化の漏れだと思う。
ふむふむ‥‥抽象化といってもいろいろあるんですね‥‥
>イテレータをコンテナ (の参照) とインデックスの組で実装すれば回避可能なわけだし。
私はイテレータはポインタの読み替えだと決め付けていたので、こういうイテレータの実装はちょっと抵抗がありますね
コンテナへの参照とインデックスを組みするとなると、これはスレッドセーフのことを考えないといけないな、と、どうしても思ってしまいます
そういうこと、すなわち必要に応じて重たいけれどもスレッドセーフにするか、それとも単一スレッド内の話だから軽く書きとばすか、というのはアプリケーション側の裁量だと思っています
言語標準で最初から「スレッドセーフにしました!」というのは、C/C++ 的にはイマイチではないかな、と >>719
> C/C++ 的にはイマイチではないかな、と
そうだよ。
C++ が C 的な考え方から離れなかった (他の方針も取れたのに) という話をしてる。
C/C++ 的にイマイチになる例を出したんだからイマイチだよ。 WebAssemblyで書かれたアプリはあるんですか? 喧嘩売りたいわけじゃないんですけど、Rustって明示性を重視してますよね、mutとか、所有権とか
でもそのくせ式としてreturnを省略できたり、でも例外はないからOptionやResultが普通でunwrap
しなくちゃならなかったり、でも>>505-508のようにメモリモデルの(まだ)定義がなく?、>>333
みたいな暗黙の再借用が出来たり色々ちぐはぐな気がするんですが、1.5、2.0辺りになったら大幅に
変わったりしますか?足を撃ち抜かないCPPとしては「良い」出来だと思うんですが、、正直、ほんの
ちょっと触ってみてCargoコンパイルが重くて、特徴の明示的など非常にめんどくさいんですがそういうもの?
C++20やC++23なんてありますが正直、もう時代の役目を終えたと感じます。いくら色々な機能を追加しても
能力次第で足を撃ち抜く事には変わりなく、そのような用途であるカーネルさえ古典的な安定したC、C++を
使いますよね。RustがWebkitを倒せたらほとんど使いどころがないような?
それと恐らく借用があるのでGCは搭載・あるいはON/OFFされないとほぼ確実に思いますが、async
awaitな非同期ではくGoのようなライトウェイトなGoroutineみたいなのが搭載される計画はありますか?
余談ですがLinux-kernelやドライバに使われると聞いているので、(標準的・言語的にはランタイムに入る事は)
無いんだと思ってますが、Goも例外は無いけど、なんであの界隈はブロック例外がアンナにも、お嫌い
なんでしょうかね?ちなみに最近、Nimというのを触ってとても感銘を受けました。 >>722
これはきちんと議論を追っているわけではなく私なりの理解だということを事前に断っておくけど、
(unsafe を除いて) メモリ管理のチェックが自動化できることが最重要の指針だと思う。
チェックするにあたって必要な情報が多いから結果的にたくさんのことを明示する必要があるけど、
曖昧さがないなら明示する必要はないし、
実際の利用でほとんど常に同じような指定をしているならそれをデフォルトにして違うときだけ指定するのでも問題にならない。 >>722
単に明示性を重視してるというよりは、分かりにくいとか非推奨とか高コストなとこは明示して
そうでないとこは省略させたいように見えるな。
例えば関数の型なんかは技術的には省略して推論できるけど
分かりにくくなるからあえて書かせるとか。
なのでreturnは自明だけどResultはちゃんと処理させたい、
という考え方かと。
goroutineみたいなのはまず入らないだろうね。
そもそもなるべく標準ライブラリは小さくする方針だし、
現状でもrayonみたいな並列処理ライブラリ使えばいいし。 >>723 >>724
なるほど、スペシャルサンクスです!メモリ管理のチェックを”最”重要視してるわけで、あまり煩雑な明示
及び、高コストな明示はしない方針だろうという事ですね。ドライバーやカーネル、OSコマンドに使われて
セキュリティホールが一掃される日が早く来てほしい。
並列処理でrayonというのがあるんですか!教えてくれてありがとうございます。確かにライブラリというか
C++のようなRTLは小さくしてほしいですね。Goのようにデカすぎるのは組み込み用途に向かないので。 goroutineの代替ならtokioとかasync-stdみたいな非同期IO系のランタイムも外せないのでは
goroutineの並列と並行のどっちの側面について言ってるのか次第ではあるけど asyncではなく、って言ってるのでrayonとかの方が近いかな、と。
まぁどっちにしてもgoroutineそのものなモデルを提供するライブラリは多分ないので
各自必要な並列並行性に応じたライブラリを選ぶ必要はある。 LinuxカーネルをRustで書こうとかいう話が去年出てたけど、
社会のインフラにもなってるようなカーネルの開発者が考えてることと
プログラミング言語で遊びたい人の考えてることが違いすぎて萎えた
しょせん、プログラミング言語なんてアセンブラとC以外は全部遊びだよね
安かろう悪かろうの遊びレベルの仕事に金払う会社があるから勘違いされやすいけど 今はカーネルモジュールを対象にRustをサポートする予定みたい
ABIとかメモリ管理まわりの差異の吸収をどうするか一番熱いところをやってるね
https://lwn.net/Articles/829858/ C/Ruby 併用のmruby の本が出た。
文字列処理などは、GC のあるRuby側で書く
Webで使えるmrubyシステムプログラミング入門、近藤宇智朗、2020/11
宇宙開発などの組み込み用、MicroPython, Lua, Squirrel の代替になる。
Ubuntu 18.04, C99 対応
人工衛星イザナギ・イザナミでも、使っている >>735
LinuxもC言語ももとはと言えばスペーストラベルってゲームで遊びたくてLinuxの前身のUNIXが作られたし、そのゲームを移植するためにB言語がつくられて、
さらにそれを改良したのがC言語だ。 なるほど。いろんなスレで同じこと書きまくってんのな >>743
Cが遊びにも使えることを主張しても反論になってないぞ RUSTはウェブとかAI分野でのバブルは考えにくい
あるとすればIOTやら組み込み向けだろう 金融でHaskell流行ったみたいな感じでrust流行ったりしないかね そもそもそんなに流行ってほしいか?
インフラとかライブラリとか地味なところで
ひっそりと使われるのが適してると思うけど。 今の様子じゃ10年経ってもなんも変わらんだろ。先のある言語じゃない。 システムプログラミング分野ではC++からRustに変わっていくんじゃないの? GAHUMが採用し出して団体まで作ったのに先がないなんてどんな世界観なんじゃ Rustが流行らなくてもRustの考え方を取り入れた言語が広まってくれればいいな やりたいことが出来るライブラリ (クレート) があるなら
言語の詳細がどうでもよくなりがちってのはあると思う。 コンストラクタ、構造体のめんどくささ考えても絶対流行らんわ。
根本的におかしい言語機能なんだよ。 プログラマーって人と違った事が好きな尖った奴のイメージがあるけど、実際は
寄らば大樹の陰で巨人が採用したプログラミング言語に従うのが吉なのだ。 rustにはコンストラクタなんていうげんごきのうはないが ボカァ、今後はC++がRustのパラダイムを吸収して (saferな書き方を提供して) Rustの役割は終わると思うね それならそれでもいいけどそうなるためにはある程度Rustの取り組みが成果を上げる必要があるわけで
C++の建て増し感も気になる C++の建て増し感はもはや長所と思うしかない
仮に今後「Rustのパラダイムを吸収する」方向に進むとしたらそれはまさに建て増しだ
個人的にはマルチパラダイムを体現してるようで結構だと思うが、建て増し感が受け入れられない人にとってはやはりクソ言語なのだろうね。C++は >>758
それ日本というかプログラマを使い捨てられる文化圏だけじゃね リナスやストールマンやヘルスバーグが興味持てばまた違って来るだろう どこかでRocketで非同期処理できるようになるって見た気がするんだけど、
ググってもそれらしき情報が見つからない。
俺の勘違い? >>766
たしか次の0.5でできるようになるはず。
gitのmasterなら試せるんじゃないかな。 >>761
それを何年も何十年も待ってる人が沢山いるけど、やらないでしょ コンパイラスイッチなりプラグマなり必要になるからそれなら新言語で、ってなっちゃうわな >>768
やらないやつはrustで書くのも無理だよ >>761
Rust が依存関係をチェックする仕組みはそういう機能があるというだけではなくて、
それで全体が統一されていることが大事でしょ。 (一部には unsafe もあるけど。)
C++ の上に Rust 的なパラダイムを建て増しして便利になることもあるかもしれないけど、
統率されていることの有用さとは別物だよ。 原理的には従来のunsafe C++にsafe C++を建て増して
既存のコードを徐々にsafeにうつしていくというのは出来そうかな。
しかし実際やるとなるとRustへの移行と同じくらい手間がかかりそう。
safe/unsafe間がFFIでなくなるのは多少楽かもだけど、
境界でsafeなことを保証するのは人間が考えないといけないし。 基本的saferで特例でunsafeとその逆じゃ全然違うからなあ 実際の機能がCのライブラリにリンクしてるだけとか、丘saferだな 上手いことsafetyにラップしてくれてればそれでいいよ safetyだと思い込めればええんやろ。単純な連中だわ。 Iterator周りのconst fn化って目処立ってたりするのかな Rustで作られた有名なものを教えてください
Rubyだったらrails、homebrewとか >>782
Servo(Firefoxのレンダリングエンジン) firecracker >>783 のところに書かれてたか・・・。 Tock/OpenTitan/OpenSKみたいなセキュリティ系のファームウェアとか
こういうのは特にアナウンスもなく採用されていくから
気づいたらみんな使ってたということになるかも。 ダメじゃん
根幹がC++
C++にタマタマ握られてる C++ の資産を (ほぼ) 一方的に利用しているのもそれはそれで気分いいじゃん? 同じ目的のために作られた道具として既存のものに取って替われないのは不名誉しかない 新紙幣発行したその日にすべての旧紙幣を使えなくすべきって主張する人? LLVMをrustで書き換えた日こそ天下か?いやいやOSのカーネルこそ 相変わらずしょーもない妄想にふけるやつしかおらんな Rustにいわゆるクラス変数みたいなものってないんですか? リーナス「オブジェクト指向のたわごとを持ち込むならRustの評価見直すぞ」 >>802
ありますけど、mutable static変数なんて扱いづらいだけですよ? Rust は色んなものをモジュール単位にしているような印象がある。
構造体のフィールドへのアクセスもモジュール内では制限がなくて、
モジュールの外に対して可視性を制御する仕組みになってるわけだし。
型の単位ではプライベートとパブリックを分ける気がない。
考え方次第ではあるけどスコープ管理の「雰囲気」からすると
C++ のクラスが Rust で言うところのモジュールに近いと言えなくもないんじゃね?
まあ前提が違うものについて無理やり共通点を見つけることにどれほど意味があるかわからんけど。 >>802
定数でよければ associated constant が使える
変数にしたいなら >>804 の言うように static 使うしかなさそう Dropboxは何のGUIライブラリで作られているのかわかりますか? >>808
rustで書き直したのはサービス側と同期エンジンじゃないかな? Rustって何で構造体のメモリーレイアウトをデフォルトでは勝手に並び替えるんだ?まじやめて欲しい
サイズを小さくする為?それとの他の理由があんのか?明示的だと言いながら余計な事ばかりすんなや 構造体の並び順はメモリーアライメントで苦労したこと無い人の意見だな。 >>810
#[repr(C)]付けないで文句言ってるならお前のせいやで? >>807
>>804
サンクス
あんまり使わない方が良さげだなあ
設計変えた方が良さそうだ 今時プラットフォームに依存する構造体のメモリーレイアウトを前提としたコードは書いちゃダメよ >>814
クラス変数って要はグローバル変数だから濫用すべきではないよ >>815
アセンブラと連携したい時には問題となりそう。
また、順序が書いたとおりの方が、色々と効率よいコードが書ける場合がある。 >>817
具体例は?
Ord::cmpがmemcmpだけでできるとか? >>817
コンパイラが十分賢くなったときに様々な最適化を自動で出来るようにする余地を残すため
デフォルトでメモリレイアウトを保証しないって設計になってるんだけど
自分で最適化する場合はコンパイラの最適化を抑止するってのはrustに限らずよくある話だしなにが不満なのかよくわからない >>810
明示的じゃん。
明示的に並べ替えを禁止する指定があるじゃん。
ほとんどの場合に順序はどうでもいいんだから、
どちらがデフォルトであるべきなのかなんて自明だろ。
条件付きだが C++ もデータメンバの順序を並び替えることは (言語仕様上は) 有りうるし、
並べ替えて良いと規定されているときに並べ替えを抑止するような指定方法はない。
(処理系の拡張としては有ったりするかもしれんが。)
Rust のほうがマシ。
現在の Rust は言語仕様と処理系の仕様の区別が曖昧なので repr が
(今後現れるかもしれない) 他の処理系でも使えるポータブルな機能なのかわからんけど。 フランスのデータセンターの火災で『Rust』はデータの大規模なロストが発生 なんか
struct Foo {
int m_a;
bool m_b;
int m_c;
bool m_d;
};
とかあったら
struct Foo {
int m_a;
int m_c;
bool m_b;
bool m_d;
};
にしたい衝動に駆られてストレスmaxなのでどうでもいい話ではない 構造体定義するときc++だとアライメントずれないように手作業でダミーのデーター詰めたりしてたけど、途中で型変えると並び替えメンドクサイ。自動で最適化してくれる方がいいし、どっちも選択出来るのだからRustの方が正しいわ。 マジかよ…
rustで書かれたゲームエンジンってのもちらほらあるんだな アライメント合わせとかコンパイラに任せたら良いし
最悪でもunionを使って型を並べたら最もアライメント条件が強い方の型に合うから
アライメント合わせの目的で手作業でダミーのデーター詰めを行うというのは都市伝説、
コンパイラがアライメントを合わせた結果としてできたPADDING部分のデータを
どうしても不定値にしたくないがmemset()で構造体全体をゼロクリアするわけにもいかないという
きわめてレアなケースでしか行わない 非同期のランタイムはtokioとasync-stdどどっちが標準になりそう? Rustの悪口言いたい訳じゃないけど、デフォルトで並び替えるのは正しく思えないわ
#[repr(C)]つけろってのはその通りだけど、組み込み用途でつけ忘れてリリースして
しまったら考えるだけで恐ろしい >>835
その程度も出来ない馬鹿だとCでやったら大惨事じゃね? デフォルトで余計なことやる設計が好きな人にはいいんじゃないの?
結局どっちに寄せるかだし。 >>835
自動ったって最適化の挙動はごく単純なルールだし、結果も解る範囲なのだからやはり問題ないとおもうけど。 メモリレイアウトのパターンを何種類か決められて、それぞれの最適化パターンに名前が付けられていくと考えれば、概念的な意思の統一がしやすくなるわけでしよ。今まで皆がバラバラにやってた方がおかしいわけで。構造体の隙間にあちこちゴミ入ってるのどれほど見たことか。 >>835
clippy の improper-ctypes-definition とかで検出できるのでは Cはコンパイラによりけりで最適化の度合いによるけど、無茶な事をしなければ基本は
書いた通りにしか動かないよ。C++のクラスは継承を使うとよう分からんレイアウトを
しくさるけど。Rustのやり方でも問題は確かにないし、結局どっちに寄せるかと言うのも
その通り。むしろゴミと言うか他人がレイアウトを整理しようとして事故るパターンの方が
多いが、まあ確かに些細な事だろう C言語でも非標準とはいえ呼び出し規約の指定とかあったなあ 付け忘れでリリースってテストもせずにリリースってこと?
確かにデフォルトで安全側に振るのはRustの基本方針だとは思うけど
全ての型をFFIする前提というのはやりすぎだと思うが。 Cは書いたとおりにしか動かないってのは単にCに対する理解度が高いだけでは
例えばアセンブリしか知らない人から見たら自動変数の振る舞いなんかは暗黙的な動作ばかりだと思うが まったくその通り
Cでは書いたとおりにしか動かない、と思うのはCにあまりにペッタリ入り込みすぎて
もはやC脳になってしまっている(なので考えずに自動でなされる変換が頭のなかでできてしまう)か
またはじつは思いこみで理解が足りてないかのどっちか 更に言えば最適化を有効にしたらかなりアクロバティックなコードを生成してくることもあるので人間には予測不能。 たいしてメモリ削減できない言語のくせに変な最適化かけんなよって話だわ Rustではunsafe使わない限りは構造体のフィールドレイアウトを変更しても問題無いので、最適化の余地を残す仕様になってるのは良い事なんでは Cが書いたとおりにしか動かないのと同様にRustも書いたとおりにしか動かないということ
構造体メンバの順序の話はrepr(C)つけたりclippy使えというのが結論で
デフォルトの挙動に違和感を覚えるか否かという話はbikeshed メンバの配置が固定だと移植性も下がるよね
パフォーマンスの低下くらいだったらかわいいけど
下手すればバスエラーで落ちる Cの常識がどこでも通用すると思ってると別の言語でも怪我しそう コンパイラに全て任せればいいって考えのやつのが実際は事故ってるがな。 何に怒ってるのかよく分からないけどコンパイラによる構造体レイアウトの最適化がデフォルトオンになってるのがそんなに気に入らないの? >>854
それは言語の問題なのか、コンパイラの問題なのか、何が事故ってるの? ていうかCコンパイラのアラインメントだって最適化の一種じゃ? そんなに気になるなら、フォークして、
デフォルトの挙動が違うrustを作れば済む話じゃないの? 最適化でunalignedになって落ちるならコンパイラのバグなんだから直せばいいし、
手動であらゆるアーキ向けにパディングを調整するよりよっぽどいいと思うけどな。 メモリレイアウトの話まだ続いてるの?
C++でダメなところ潰して制約強めでバグ出にくくしようって言語で、コンパイラが信じられないと言われてもコンセプトが違うとしか C++でダメなところ潰して制約強めでバグ出にくくしようってのと、
コンパイラが信じられないからコンパイラ設計を楽にしようってのは別に矛盾しないがな。
頭悪すぎ。 コンパイラ設計を楽にするって、例えばどういうこと? ここまでの流れでコンパイラがバグるほど難しい事してないと思うけど。何を心配してるの? 何が問題なのかiefoneか何かで実例出して欲しいな 問題になるのは外部リンゲージな関数で構造体を渡すときだと思うが
コンパイルした後リンクするみたいな本番行為ってiefoneできるんでしたっけ ウィンドーズのAPIの構造体みたいにメンバの数が異なる構造体のシリーズで
先頭部分は同じレイアウトであって欲しい、みたいな要請がある場合は
いかに自動レイアウトの規則が厳格に決まっていても問題を生じるし、
テストで見つけろといっても限界がある
メンバ数3、4、5はOKだった!→56億年後に弥勒菩薩が6番目のメンバをboolにしたらすべて崩れ去った、みたいな それとも何かねここで言うテストというのはコンパイラの
自動レイアウトするロジックを見通したホワイトボックステストで
カバレッジ100%を目指せというのかね? かなり減る64 bit整数m個とbool m+1個の構造体で#pragma pack(〜)とかしない場合
順序依存で8*m + 8*(m+1)バイトになるか8*m + ceil((m+1)/8)バイトで済むかの違いがある
引いたらどれだけ減ったかワカル C++だって処理系によってABI違って互換性無いのになに寝ぼけた事言ってんだ状態 ヒエッ…日本語でどづぞ
>>877
処理系がABIを決めるケースはまれ
宇宙誕生以来一桁あるかどうか メーリングリストでそれらを主張してみてはどうか?ここで言ってもrust下げとしか見られない さっぱりわかんねえんだが、
>先頭部分は同じレイアウトであって欲しい、みたいな要請がある場合は
こんなクソみたいな要請がある案件の場合はrepr(c)でいいんちゃうん? スマン>>878はstdcallを念頭に言ったがcdeclはC言語処理系によって決まったと言ってよいかもしれませんねーorz
stdcallの発祥がWindowsとPascalのどちらが先なのかは知りま栓、
>880
>こんなクソみたいな要請がある案件の場合はrepr(c)でいいんちゃうん?
禿げしく同意 >>871
言われてみれば確かに。
alignmentはCPUのBIT数が同じであれば大体同じなので、自動でやってくれもよい
場合も有るが、順序まで変えたのでは困るな。 repr(C)をつけるのでは駄目な理由は誰も言えないのか おじいちゃんが今際の際に「repr(C)は使うな…ガクッ」って言ってたんよ… 不満があっても使い続ける必要があるなら、
フォークしちゃえばいいじゃん。
もやもやしつつ使い続けるのは、良くないよ。 C/C++をいまさらフォークしたところで誰も見向きもせず
個人で使うだけで消えていくだけだろうが
rustなら「おっ、おれもこういうのが欲しかった!」
ってやつがむらがってきてワンチャン有名なれる・・かも? >>887
一貫性のあるc--ができたら可能性あるよ。 >>885
同じおじいちゃんが原理主義者になるなってのも言ってただろうに。 Cargo.tomlかなんかでデフォルトのreprを設定できればいいんすか?
俺は要らんけど repr(C)がついてないデータ型に警告出すようなlint書いてclippyにpullreq出せば良いのでは 別に
構造体XのメモリレイアウトをRustのデフォルトとすべきなのかrepr(C)で扱ってほしいのか(あるいはその他か)は
構造体Xを定義したときに定義した人の意向で決まるから何の問題も無い
別の人が構造体Xを間違ったメモリレイアウトで解釈するプログラムを書く危険性は
(わざとそうするのでもない限り)無い 、と思うんだけどrepr指定が異なる構造体はちゃんと別の型とみなされるの?
つまりrepr(C)のメモリレイアウトな構造体を、(例えば)repr(PACKED)なメモリレイアウトな構造体を引数にとる関数に
渡せてしまうとかあると悲劇なわけだが
Rust使ったことないからよくわからないので教えてくだちい、 >>894
一つの型には一つしかrepr指定できないから指定を変えたければ別の型にするしかないよ
unsafeなtransmuteで強引に変換することは可能だけど、それは当然変換した人の責任 >>874
組み込みの場合、rustのランタイムの大きさ考えたらその程度じゃ全然埋まらないんだが。。
結局まともなユースケースを考えてないんだろうね。 stdがでかいって話かな?
なんかそれも問題になって対応策はあった気がするけど デフォルトでは利便性やリンクの高速化のために大きくなってるけど
組み込み用途ならちゃんと最小化する方法はあるし
Cと同程度まで縮むよ >>896
下記の記事の Executable sizes の節で実行ファイルのサイズについてCとの比較を考察してた
サイズ削減する方法も書いてあったよ
https://kornel.ski/rust-c-speed ちょびっとだけどついにlinux-nextにrustで書かれたコードが入ったか >>896
組み込みデバイスでrustを使いやすくしようとしてるワーキンググループあるから
どういうところで不便に思っているのかコメント寄せてあげたら良いのでは
https://github.com/rust-embedded/wg
issueでコメント募集してるよ 依存しているクレートが多いとビルドが長い、いい加減にしろ。なんじゃこりゃ >>901
だから考えてるスケールが全然違うっつーの Rust の実行ファイルが大きくなりがちなのは何でもかんでもスタティックリンクする文化であって、
そうしてでもうんざりするような (実行時の) 依存関係に悩まされたくないという話なので、
不要なもので肥大化しているわけじゃないよ。 本来必要なものがあるだけ。
もちろん制約の大きい組み込み環境でごく基本的なライブラリすら制約してまで
大きさを削ったら使い勝手は悪いだろうけど、
それは Rust に限った話でもない当たり前のことだし。
メモリが数キロバイトとかいうレベルだったら (少なくとも現時点では) Rust が不向きというのはそうかもしれない。
そんで特に Rust を使いたいというケースでもない。 >>906
具体的に言語化できる能力あったらこんなとこで愚痴垂れてないでしょう Linuxのディストロだとなるべくダイナミックリンクにするようにしてると思うんだけど
Rust製ツールとその方針の相性悪い気がする Q. Rustの倒し方を教えて下さい
A. まずデータセンターを燃やします
フランスのデータセンターで火災…『Rust』に復元不可能なデータロストが発生するなど大規模被害に発展 | エンタメウィーク
https://ent.smt.docomo.ne.jp/article/8989583 Rustってなんか日本人的にわびさびっぽい名前でいいよな そこんところは golang とか rustlang とか書く風習が出来てるから
たいした問題ではないんだが、 C のことを clang とか書き始めるやつが出てきてクソッタレという感じ。
よそでどんな習慣が出来てもいいけど変な汚染するなよな〜〜という。 LLVM ClangはふつうClangて書かない? Clang は Clang のことなので
C のことを Clang っていわれると困るって話 >>909
というよりその方針だとsoのバージョン非互換で問題が起きて大変なので
GoやRustなど最近の言語はダイナミックリンクを避けている。 >>917
ディストロがビルドして配るバイナリの話だからバージョン非互換は関係ないのでは
非互換が問題になるならソースにパッチ当てられる訳だし
goも同じ問題があるというのはそうだけど >>919
そもそも最近はディストロのパッケージ管理システムに乗りたくなくなっているのでは?いろいろなディストロのいろいろなバージョンに対してバイナリを提供すること自体が大変で。
Gentooやってると依存関係ミスっててコンパイルこけるとかよくある。
(そういう意味でもGoやRustはかなりコンパイルに失敗しづらくて安心感はある)
退化している感もあるけど、GitHubで全ディストロ対応のシングルバイナリ配るのが結局楽だった、という感じなのかも。 場合によっては違うバージョンのライブラリが共存することもあるし
ファイル名のルールでどうにかしたりはすごく面倒
近頃はコンテナにまるごと突っ込むとか言った解決法も取れるが、
それなら全部スタティックリンクしたらええやんというのは
順当な方針だよな パッケージのバージョン管理とかRustは最近のnpmばりによくできてるんじゃないの
知らんけど >>921
gcc コマンドの実態が clang の環境が
存在するのでそれを茶化したジョークだと思う Ruby, Python, Rとか言語独自のパッケージ管理システムもありつつ
同時にディストロのパッケージ管理システムにも有名ライブラリだけは乗ってたりして
なんか二重管理みたいな変な事になってる 開発環境が用意するパッケージ管理は開発環境の管理だし
ディストリビューションの管理は実行環境の管理なんだけど、
ライブラリが実行環境なのか開発環境なのかは不可分な部分もあって単純に二分できんのよ。
C/C++ のライブラリのパッケージ管理が発展してないのは伝統的に
ディストリビューションのパッケージ管理に全力で乗っかる文化があったからで、
モダンな開発環境は分けようとしてかえってややこしくしているような気もする。
元々あった問題があぶりだされただけかもしれんけど。 まあlibcのバージョン違いで困った経験あると、スタティックリンクはやむ無しって思うけど。 >>913
コンパイラをclangという名前にしてしまったAppleが馬鹿なだけ。
ライバルにMSのcl.exeというものが30年ほど前からあるだけでも
ややこしいのに。 >>926
C/C++全盛の頃はコードを書く人と使う人が一致してることが多かったから問題なかった気がする。
自分の環境さえ正しくセットアップすればそれで問題ないという。
今みたいにGitHubでコード共有するのが当然って世界だと違う環境でビルドするのが困難ってのはきつい。
OSSのC++ライブラリを使おうとしたときに、作者と違うディストリビューション使ってる場合、ほぼ確実になんらかのトラブルにはまる印象だなぁ。 てか低レイヤー依存のパッケージは言語パッケージ管理じゃ扱いづらいだろ。 >>928
自分の開発環境に cl.exe があるのを見つけて
「あれ? Common Lisp なんか入れたっけ?」って思ったことがある。 Rustと関係ない雑談はそろそろよそでやって下さいね 次世代言語21 Go Nim Rust Swift Kotlin TypeScript
https://mevius.5ch.net/test/read.cgi/tech/1587276362/
あっちのスレの流れの中に投下するものがこっちに誤爆して話題が続いてるだけだぞ 親善試合のプレー中でもないのにパンチを繰り出し、歯を折る韓国人の本質 >>939
証明論関係はプロトコル検証なんかには使えるかもね。 PDA以上の機械はどうやって機械的に証明したらいいんじゃ…… ZDNet Japan: トーバルズ氏が考える、LinuxにおけるRustの居場所とは.
https://japan.zdnet.com/article/35168533/ >要するに、Linuxの記述言語がCからRustへと変わる日は当面の間やってこないだろう。その一方で、Rustベースのプログラムやドライバーをユーザー空間で実行するということに対する関心は高く、それに向けた動きは数多くあるため、いつの日にかLinuxというOSでRustベースのカーネルが採用されるだろう。
まあ当たり前の結論だわな。 Javaやpythonのようなバブルは無いだろうが一定の需要はあるだろう 競技プログラミング分野で謎の注目を集めてるよRust
短時間とか早解きが重要なコンテストでは雑に書けないので使いづらいが、長期間のコンテストでは重宝されてる
強い人たちが使ってるのもあって まあ9割は単なるファッションだろ。
実際使ってみるとc++で気をつけるのとほぼ変わらんしそれができる輩しかまともに使いこなせん。 そもそもデバドラならC++でもいいんちゃうん?
Linusが問答無用で許さない感じ? >>954
昔LinusはC++をボロクソに言ってた。特に例外周りがカーネルとは合わないとかだったかな。
今の改心したLinusなら違うかもしれないが。 C++は罵詈雑言で二度とそんなこと言うな
ぐらいで叩いてた 思いっきり皮肉だけど「C++独自の機能を使わないならC++でも構わない」みたいなこと言ってなかったっけ オブジェクト指向はクソみたいなのも言ってた気がするし、
当時Linusが文句言ってたポイントをRustはうまく回避してるかも。 linusはオブジェクト指向はファイルシステム周りでは有効って昔から言ってる。
流石にこの辺りの感覚は鋭いわ。 あぁ確かにオブジェクト指向というよりC++のそれにまつわる機能がクソって話だったね。 そうは言ってもリナス自身が言語処理系に手を出す事は無いんだろうな >https://japan.zdnet.com/article/35168533/
これも年取ったからだいぶ穏やかに答えてるけど内心は
「とりあえずデバイスドライバーで実装してみろやwやれるもんならなw」って感じだと思うぞ。 >>955
https://tabesugi.net/memo/2009/1a.html
Date: Thu, 6 Sep 2007 18:50:28 +0100 (BST)
Message-ID: <alpine.LFD.0.999.0709061839510.5626@evo.linux-foundation.org>
C++ はひどい言語だ。これは、多くの平均以下のプログラマーが使ってるために
さらに輪をかけてゲロゲロになっていて、どうしようもないゴミが
簡単に生産されるようになってる。正直いって、C を選ぶ理由が C++ プログラマーを
追っぱらうため *だけ* だったとしても、それ自体、C を使う強力な理由になりうる。
C++ はトンでもなく悪い設計の元になりうる。どうせこの言語ではいつも STL やら
Boost やら、その他ゲロゲロベロベロの「素敵な」ライブラリの機能を使って、
それがあんたのプログラムに「役立つ」んだろうが、以下のことが起きる:
- うまく動かないときにもたらされる際限のない苦痛 (あと STL とか、特に Boost が
安定してるとか移植性があるとかいう奴は、どいつもこいつも大ウソつきで、
もはや笑えるレベルを超えている)
- 非効率な抽象プログラミングモデルで、2年たった後にこれらが実はそんなに
効率的じゃなかったことに気づくケース。でもそのときにはすでに全部の
コードがその素晴らしいオブジェクトモデルに依存していて、直すためには
アプリ全体を書き直さなきゃなんない。
言いかえれば、唯一まともで、効率がよくて、システムレベルで使えて、移植性がある
C++ ってのは、基本的に C で使える機能だけに限ったときなんだ。そして C だけに
限定するってことは、他の人がそれをめちゃくちゃにしないってことで、
ついでに沢山のプログラマが実際に低水準の問題を理解することができて、アホらしい
「オブジェクト・モデル」のたわごとを持ちこまないってことだ。 >>956
>C++は罵詈雑言で二度とそんなこと言うな
>ぐらいで叩いてた
>>964
>正直いって、C を選ぶ理由が C++ プログラマーを追っぱらうため *だけ* だったとしても、それ自体、C を使う強力な理由になりうる。 >>957
>思いっきり皮肉だけど「C++独自の機能を使わないならC++でも構わない」みたいなこと言ってなかったっけ
>>964
>唯一まともで、効率がよくて、システムレベルで使えて、移植性があるC++ ってのは、基本的に C で使える機能だけに限ったときなんだ。 >>958
>オブジェクト指向はクソみたいなのも言ってた気がするし、
>>964
>C だけに限定するってことは、他の人がそれをめちゃくちゃにしないってことで、
>ついでに沢山のプログラマが実際に低水準の問題を理解することができて、
>アホらしい「オブジェクト・モデル」のたわごとを持ちこまないってことだ。
>アホらしい「オブジェクト・モデル」のたわごとを持ちこまないってことだ。
>アホらしい「オブジェクト・モデル」のたわごとを持ちこまないってことだ。
>アホらしい「オブジェクト・モデル」のたわごとを持ちこまないってことだ。
>アホらしい「オブジェクト・モデル」のたわごとを持ちこまないってことだ。
>アホらしい「オブジェクト・モデル」のたわごとを持ちこまないってことだ。 しかしこの話ももう15年近く前だし、C++20についてどう思ってるのかは気になるな。
相変わらずボロクソなのか、もう少し丸くなってるのか。 >>963
残念ながらlinusは俺の10倍はひねくれてるよ 色々な言語を扱ってみればどんな言語でも"トンでもなく悪い設計の元になりうる"のは
Linusも気がついてるんだろうが、こういう手合いは
単に自分の好みで気にいらない事を否定するのに「一般的に良くないものだ」という
主張を持ちだすから始末がわるい
またこの手の攻撃的な人物は自分の周囲の人間が一般的であると思い込む傾向もあり
たしかにLinuxとオープンソース界隈の人間がC++を使いまくると"トンでもなく悪い設計"に
なりやすいだろうなというのもわかる(そういう界隈の人間は基本的に自由であり
自由にできる幅があるときは自分の思いついた"カッコイイやりかた"をすぐ人におしつけたがる) C++ネタになると書き込みするやつが急に増えるんだからwww
いい加減C++スレでやってね C++に勝てるっていう宣伝文句に惹かれて興味を持った人が多いのだから、本当にC++より良いのかっていうところに焦点が当たるのは宿命 >>953
C++ の仕様に違反せずに書くために「気を付ける」程度で本当に足りるのか?
足りないからそこそこの規模のプロジェクトになったら valgrind とかのツールを導入するはめになるんだろ。
十分に知識を持っていても隅から隅まで 100% に配慮するのは無理ってのがわかってるから、
C++ で気を付けるのとほぼ変わらんなら Rust を導入する意義はある。 規模が大きくなって関わる人数も増えれば気を付けるのもかなりのストレスだしなあ C++より安全という声は多いが誰がC++に勝てるなんて言っているんだ? c++でもuniqueptrなりconstなりmoveなりはあるわけで、かける人は同じように書けるだろ。
結局かける奴は書けるしかけない奴は書けないってのはどっち使っても一緒だわ 昔は隅々まで配慮できる集中力があった気がするけど
歳とともに無理になってくるからコンパイラに指摘してもらったほうが楽。
いつまでも完璧なC++が書けるならそれはそれで羨ましい。 高度な技術と集中力でミスなく実行すれば
バグは発生しないという妄想に付き合うほど
みんな暇じゃないんだなあ だから問題あれば自然にコンパイラで引っ掛かるような書き方してるって話なのに全く通じてねーなこのバカ。 気をつければ大丈夫の域出てなくて笑う
コンピュータの仕事してるとは思えない、 >>980
C++ってmoveされた後のオブジェクトに触って警告とか出ましたっけ?? そんなところでミスしてなぜかテストも書かない輩みたいな馬鹿を想定する意味がわからん。。
とことん自分の都合のいい馬鹿ユーザーしか想定してないってのが丸わかりだわ。 そうだぞC++が使いこなせないのはお前らがバカだからだ
根性で頑張れや そうだぞC++で出るバグや脆弱性はテストで全て回避出来るからな
死ぬ気でテスト書かないと駄目だぞ
コンパイラの警告なんかに頼るのは負けだと思え C++はメモリへのアクセスの回数やパターンが見た目からはわかりにくいコード
(コードからメモリが透けて見えないコード)にすぐなるから
カーネル製作者としては許容し難い、というのが主要な反対理由のはず 言語がRustであってもC++的な書き方をしているのを見たら怒り狂うことは必定 指差し確認しながらコード書くべしとか言ってる馬鹿と変わらんな c++でまともに書けない奴がなぜかrustを使うと書けるようになるとかいうファンタジーを信じるバカの多さよ。。 「気をつければ大丈夫」みたいな根拠無き精神論って日本の生産性が低い一因だよな 関数粒度を揃えるとかも根性論だとか思っちゃうバカなんだろうな。。 せやせやまずc++でテスト100万行書いてから文句言え C++のテストフレームワークって基本的にクソマクロ触らされるからやだ はいはい、まともにrustでc++並の開発速度で製品作ってから言えや。 このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 222日 20時間 33分 33秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。