Rust part8
■ このスレッドは過去ログ倉庫に格納されています
>>726 海外のサイトでも、RustはC/C++から単純移行ができ無い事が問題とされている。 FortranからCへは単純移行が出来たからCが普及したと書いてあった。 >>726 後付ではない。 C++で、pChild、pNextと言えば、当然そういう構造体になる。 >>727 型・寿命・所有権の条件が同じならヒープかスタックかというのは関係ない。 お前が結果的に違う条件で書いるだけ。 >>728 知らんがな。 同じように書けるんなら新しい言語を導入する意味ないだろ。 制約が厳しい替わりに問題点が検出されやすいのが Rust の利点なんだから、 その利点が要らんなら別に Rust を使わんでいいよ。 >>730 >型・寿命・所有権の条件が同じならヒープかスタックかというのは関係ない。 >お前が結果的に違う条件で書いるだけ。 1.実験してみたところ、>>727 でBoxをRcに変えてもエラーのままだった。 2.単純にTAaaをスタックに確保した場合、正常にコンパイルされた。 3.TAaaを以下のようにHeapに確保した場合も、正常にコンパイルされた: fn main() { let bbb = Box::new( TAaa { x : Box::new(333), y : 444 } ); println!( "bbb = {:#?}", bbb ); println!( "bbb.x = {:#?}", bbb.x ); println!( "let x = bbb.x;" ); let x = bbb.x; println!( "x = {:#?}", x ); } つまり、Vec<TAaa>の場合にだけエラーになる。 >>731 ついでに言えば >>727 のエラーが出る行を let ref x = vec[0].x; とか let x = vec.swap_remove(0); とか let x = vec[0].x.clone(); とかすることでもコンパイルは通る。 >>732 >let x = vec.swap_remove(0); let x = vec.swap_remove(0).x のことかな? rustじゃ書けないおじさんのコードを添削する流れ、何度目だ >>733 おっと、せやな。 .x が無くてもコンパイルは通ってしまうからミスったわ。 >>734 ワイも初心者ではあるんよ。 The book (第二版の日本語訳の無料で読めるやつ) を読み終わって、試しに 500 行くらいのコードを書いてみたって程度。 本を読んでいる間はコードを書いてない。 手を動かすと理解しやすいという人も多いけど、 感覚でやってしまいがちで書いてある理屈をしっかり把握するのが疎かになる気がするから。 で、 The book を読めばこの程度には理解できるので理解できてないやつは単にアホという証明でもあるし、 逆に返答に詰るようなら俺がまだ入門級のことが理解できてない (どこが理解できていないか) ことがわかるので 練習の題材としてちょうどいいわという気持ちで相手してた。 >>738 では、>>732 で >let ref x = vec[0].x; の borrow が合法かどうか、どうやってコンパイラが静的に解析しているか アルゴリズムを説明してみてください。 >>739 let ref というのは直接的には The book に出てこないと思うけど、 let もパターンマッチだということはタプルの項目で示されている。 たとえば let a = &1; と書いたら a には 1 の参照が入るし、 let &a = &1; と書いたら a は (参照を経由する) 値になる。 参照にマッチするのではなく値にマッチさせた上で参照が欲しいときに使うのが ref であるということは match の説明の中にある。 つまりこの場合に let ref x = vec[0].x; というのは let x = &(vec[0].x); と書くのと理屈は同じ。 公式で丁寧にしかも無料で公開されてる本もろくに読めないガイジたちがわらわらするスレになっちまったな ちょっと名が知れ渡っただけでこんなことになんだから、一般的になったらとんでもないな rust+wasmちょっとやってみたけど、単純な処理に記述だけが無駄に複雑になりすぎる 組み込みとかシステム系で使われそうだけど、一般的とか言う広く色々な使われ方はしないだろコレ JSみたいに直接DOM触れて、直接実行できるなら普及するけど、現状のめんどくささならなぁ・・・ >>740 それは分かっている。 iとjがループ内で変化したような場合、 vec[i].x からmutableで借用した場合、 vec[j].x からimmutableで借用できるかどうかの判定をコンパイラが一般的に行うのが難しいんだよ。 だからそのアルゴリズムを理解しているのかと聞いている。 >>744 似た例で言えば、 dst[i]をmutableで借用した場合、src[i]をimmutableで借用しようとしたときに、 srcとdstが同じアドレスに被って無いかの判定が静的には物凄く難しいと されているので、エラーになってしまうかも知れないというようなことを心配 しているんだよ。 >>745 もっとちゃんと書くと、 src[0]〜src[99]までに対して処理するような場合だと、src[i]をaに借用してから f(a)、g(a)、h(a)に順番に渡して何か処理するようなことは出来ると思われるが、 ここに、dst[0]〜dst[99]も加わって、dst[j]をbにmutableで借用 しようとすると、mutableで借用した場合にimmutableでは借用できないというルールを この場合にはコンパイラが静的には判断できなくなってコンパイル・エラーになって しまう可能性を心配している。 つまり、コンパイルの借用チェッカは、予めよくあるパターンに対して特別な 処理を実装している場合には通るが、一般的には判断できるわけ無いので通らない のではないかと考えられるんだよ。 let x = 5; println!("{}", if 0 < x < 10 { "in" } else { "out" }); この比較方法ができない理由ってなんかある?例えば最適化に響く?とか 可読性も労力もこれ出来たほうがいいと思うんだけど 最初の比較でBoolになってんのを整数と比較してるからじぇね? 特に可読性が上がるとも思わないし、むしろ老眼で見逃す勢が出るから&&挟んだ方が見やすいな その書き方ができる言語は割と少数派な気がする pythonではできるが a < x > b これを見て何がしたいのか直感的に理解できる人間は多数派ではないだろう 結局 lb < x < ub のパターンしか使わないんなら range で十分 >>744-746 こういう感じの話? (※ 構造体を介する意味がないのでこの例では省略) fn bar(vec: &mut Vec<usize>, i: usize, j: usize) { let ref x = vec[i]; let ref mut y = vec[j]; // エラー println!("{:#?} {:#?}", x, y); } fn main() { let mut vec: Vec<usize> = vec![1, 2, 3]; bar(&mut vec, 0, 1); } vec の所有権が貸し出されるので一律に出来ない。 可能性を心配する必要はないよ。 普通の借用ルールが適用されて確実に出来ない。 (unsafe を使わない限り。) しかもそいつら繋がってんのな、Rust大嫌いなのに隠してここでやりとりしてんのな とりあえず二人とも気持ち悪いからミュート、ブロックした https://qiita.com/Yutaka_Aoki https://qiita.com/SFITB 少なくともMozillaのステマが〜とか言ってた頃よりだいぶましだと思うが。 dropが飴玉みたいって批判?がちょっと面白かった。 その発想はなかった的な。 drop out とか drop off とかのニュアンスでしょ? スコープから消えろという意味での drop であって、結果的に解体もするというのは実装側の都合だよな。 その型を利用する側の都合からするとただ消えろって話なので、drop という語をあてるのは Rust 的にはそこそこ妥当な選択だと思える。 やることが同じだから同じというのは抽象化を軽視する暴論だ。 linuxカーネルでキャッシュをドロップする、みたいなのが用法としては近いのかな。 >>756 https://twitter.com/YutakaAoki3/status/1270069950581858309 同一人物説 dropって命名はかなり絶妙だと思う。 時点でscoped outから取ってoutとかがいいと思うけど、outだけだと抽象的すぎるからdropが一番いい https://twitter.com/5chan_nel (5ch newer account) そもそもdropって表現使ってる言語なんかなかったっけ?? ネイティブが決めた名前をJapsが文句言うのは流石に草 実際にプログラミングするのは英語話者ばかりではないので 既に浸透した用語を使って欲しいというのはわからんでもないんだが、 似て非なるものに同じ名前を与えると調べにくかったりすることもあるしなぁ。 他の言語からの「移行」という視線でばかり見ていると良くなった部分も移行コストに見えてしまうんだなというのはわかった。 そもそもdropについて言えば既存の言語でも free, delete, dispose, finalizeとバラバラなので 浸透もクソもない。 それぞれの用語の大まかな使い分けはあるけども、 じゃあ drop がそのどれかに当てはまるかといえば当てはまらないし。 qiitaの記事数は、Rustに対し、Goが8倍、Kotlinが1.5倍、C++が50倍、Javaが16倍。 唯一、Haskelに対しては、Rustは、100倍以上の記事数がある。 Haskelは触ったことのある人数で言えばRustよりずっと多いだろうけど、マサカリが怖くて記事書きづらいんだろう 宣言型マクロでRustの処理書けない理由ってある? 今のパターンマッチ風構文で作ったから処理文入れるところがない的な? ガチ関数型と違って難しいポイントはただ複雑なだけなので、頭悪くても慣れさえすればマウンティングしやすいのが人気の理由だと思ってる 「一番愛する言語」と聞かれたら、C++もC#もJSもPythonも全面的に好きで 使ってるわけではないから、消去法でRustを選ぶしかない。 そもそも愛すべき言語なんて一般人にはあるわけ無いし。 Rustだったら「愛すべき」と公表しても馬鹿にされないで済むみたいな。 他のどの言語を選んでも、白い目で見られそうだから。 ドキュメントを眺めてたら >>587 は Nightly ではこんな感じで書けるかなって思った。 https://play.rust-lang.org/?version=nightly& ;mode=debug&edition=2018&gist=75b0cca2f785445e707b113c1bce3b55 >>774 SOのサーベイのことをいってるなら、あれは別に「愛する言語は何ですか?」というアンケートではないので「愛する」と日本語で考えてもあまり意味ないぞ。 いまRustを使っていて今後も使い続けたいですか?という質問の集計結果をmost loved languageと表現してるだけ。 だから仕事で(嫌々でも)使わざるを得ない言語は低く出るし、Rustみたいに趣味で選んでる言語は高く出るのだろう。 >>776 Rustを愛すると答えた人でも、 使っている人は5%程度しかいないと書いてあったから、 「いまRustを使っていて今後も使い続けたいですか?という質問の集計結果」 とは違うはずだ。 使って無い人も「好き」と言えた訳だから。 >>777 ちょっと正確な質問は忘れたけど、 問1 最近よく使う言語はなんですか? 問2 その言語を今後も使い続けたいですか? みたいな質問で、1でRustと答えた人の86%が2でyesと答えたって話。 (で、その86%ってのが全言語で1位だった) なので5%の人しか使ってないというのとは別に矛盾しないし、 Rustを使ってない人の意見はそもそも反映されない。 このあたり元のアンケートに答えた人や SOのレポートを隅々まで読んだ人なら分かるんだけど ニュースサイトの伝言ゲームで「最も人気のある言語」とかになってしまうと ものすごく語弊があるんだよな。 >>778 あれ? それだと、全体の母集団の中でRustを使っている人が5%ということになってしまい、 「Rustが好きです」、と答えた人でも 95%が使ってないということとは違ってくるよ。 >>780 使ってる人が5%というのは合ってて、 その5%のうちの86%が今後も使いたいってこと。 だからRustを好きな人が多いんじゃなくて、好きな人の割合が高いというだけ。 実際に好きな人の絶対数でいけば、ユーザーの多いPythonとかが圧勝だと思う。 >>775 Default::default() が panic したときに drop で未初期化領域アクセスして UB になりそう >>783 unwind の段階でってことですか? >>784 そう 何らかの工夫を入れないといけない気がする 要素がMaybeUninitなので未初期化領域にアクセスすることはないだろうけど、逆に初期化済みの領域が解放されずに残るような? >>786 panic したときのことなので UB でさえなければメモリが解放されないのは問題にならないと思いますが。 copylessっつうcrateがあるからそれ使うか参考にするといいかもよ >>783 Default::default() が panic起こす実装してるからUB以前にそこを直すべきだと思うけど違う? playgroundで手続きマクロ書きたいんだけど #![crate_type="proc-macro"] で出来なくてCargo.tomlも触れないから変更出来ないんだけどどうやっても触れない?? 弱参照を多用する人っていないの?unsafeが基本? こういうコードを書いててどこを直せばいいかわかんないので教えてーー https://play.rust-lang.org/?version=stable& ;mode=debug&edition=2018&gist=4ce583191e5b07279b8ec65ef5198456 AddAssign の型引数のところに与えてるライフタイムがおかしいとは思うんだけど、 どう直せばいいかわかんない。 この書き方だと += の左辺以上の寿命を右辺が持ってるという意味になるの? あんまり詳しくないけど、ライフタイムのその書き方でエラーなるってバグじゃない?(推論力の問題?) 個人的に気になるから詳しい人教えて欲しいな 一応これで治るけど impl<T: AddAssign<T> + From<usize> + Clone> Iterator for Fibonacci<T> { type Item = T; fn next(&mut self) -> Option<T> { swap(&mut self.f0, &mut self.f1); self.f1 += self.f0.clone(); Some(self.f0.clone()) } } デフォルトで usize を基礎に据えているんですが、 BigUint なども効率的に扱いたいので clone はなるべく少なくしたいという意図で参照で受け取る AddAssign を前提にしたいんですよね……。 >>793 これでどう? impl<T> Iterator for Fibonacci<T> where T: From<usize> + Clone, T: for<'a> AddAssign<&'a T> >>796 期待通り動きました! for の使い方について調べたところこのへんにあるのを見つけたのですが、 どうにもはっきりとは理解できてないです。 https://doc.rust-lang.org/nomicon/hrtb.html AddAssign が必要とされる個別の場面まで寿命の推測を遅らせるみたいな感じですかね? むしろ >>793 がどう解釈されてしまっていたのかにも解説が欲しい…… なんか見覚えある気がすると思って考えてたんだけど、 Haskell の forall と似てるんだな。 >>793 だと Fibonacci<T> の T の制約として解釈されてしまうから、 'a は Fibonacci<T> と同じ寿命ってことになっちゃうわけか。 あるフォルダーに入っているファイルをWeb経由で見れるようにしたいのだがそういったことができるクレートあったりしますか? 現在Actix+teraで実装しようと考えていますがなかなかうまくいかないので・・・ python3 -m http.server 8000 actix-webとactix-filesではだめなの Ruby なら、コマンドプロンプト・PowerShell から、1-liner で、 Rubyで作られた遅いウェブサーバー、WEBrick が起動する ruby -run -e httpd . -p 8080 そのフォルダに、index.html があれば、これでブラウザからアクセスできる http://localhost:8080 >>803 rustのスレまで出張ってくるなよジジイ なぜrustでactix+tera を使いたいのか 学習目的? そういや、actixの作者がやる気なくしてた問題は解決したの? あの「とほほのWWW入門」に「Rust」と「Go言語」の入門コンテンツ追加へ【やじうまWatch】 - INTERNET Watch https://internet.watch.impress.co.jp/docs/yajiuma/1260986.html このサイトまだあったんだな >>805 あのテンプレートの書き方がDjangoに似てたので・・・(じゃあPythonでやれっていうのはなしで) 別に使わなくてもできるのならそれでいいんですが この前作ったツールではrouilleを使った CLIツールにおまけのWeb UIを付けるため シンプルで良かった アプリケーションの設定を管理するようなライブラリで変更時に知らせてくれるような機能があるのってgioクレートのSettings以外になんかありませんか? const fn b(s: &'static str) -> usize { s.len() } fn a(s: &'static str) -> usize { b(s) } a("c"); const fn のこの例ってこの下に置き換えられる? それともaがconstじゃないから置き換わらない? fn a(s: &'static str) -> usize { 1 } >>812 定数伝搬の最適化はconstとは関係なくかかるので その例なら1になるかと。 const fnはconst値にバインドできるかどうか、というだけのはず。 >>813 じゃあハッシュテーブルとかのキー定数とかもコンパイル時にハッシュになってるの? ハッシュ値の生成に乱数使ってるからコンパイル時には決定できないはず const fn な hasher が仮に存在するならハッシュ値まで生成されるかもしれなち >>816 ハッシュに乱数を混ぜるのは普通にある。 もちろんそのハッシュテーブルの寿命の間は一貫した値を使うけど。 普通に、はなくね? 素数のマジックナンバーと比較してデメリットしかない 汎用性が下がる コードが煩雑になる テーブルサイズの整数倍になって効率低下する確率が上がる >>817 >ハッシュテーブルの寿命の間は一貫した値を使うけど。 キーの値から、ハッシュ値を計算する際、乱数を使っていて、 一貫した値をどうやって取得するの。 // pszKey = キーの0終端文字列 // 戻り値 = キーに対応した Hash値 DWORD CalcHash( const char *pszKey ) { DWORD hash; ・・・ hash += 乱数; // こんな風にして、どうやって一貫性を確保する?? ・・・ return hash; } hasherの初期化に乱数使う ハッシュ値の生成のされ方が決定的だと ユーザーが悪意のある入力列を与えることでハッシュ値の衝突を起こしてシステム負荷を高めるような攻撃ができちゃうのよ それを避けるために多くの処理系では hasher の初期化に乱数を使ってハッシュ値の生成のされ方を予測しにくいようにしている 乱数使うのは hasher の初期化だけで、 その後のハッシュ値計算は当然乱数は使わない システム負荷を高めるような攻撃を回避するのって初期化に乱数使うとかじゃなくて、ハッシュテーブルの実装次第じゃね? システム再起動の時に乱数で変わってたら保存してるハッシュと違くなるって整合性ぐちゃぐちゃすぎる ちなみにRustは初期化に乱数使ってないけどどの言語がそれに当たるの? 悪いけどホラ吹いてるようにしてみえない >>824 By default, HashMap uses a hashing algorithm selected to provide resistance against HashDoS attacks. The algorithm is randomly seeded and … https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html ハッシュの生成はアルゴリズムに対して決定的なんだからハッシャーがどうのなんて馬鹿げてる ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる