Rust part8
■ このスレッドは過去ログ倉庫に格納されています
>>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 ハッシュの生成はアルゴリズムに対して決定的なんだからハッシャーがどうのなんて馬鹿げてる Result<T,E> を要素とするイテレータを Result<Vec<T>,E> にしたくて、
よくありそうなパターンだと思うんだけどさらっと上手くやる方法ってないもんかな? >>828
collectがいい感じにやってくれるよ。 collect::<Result<Vec<_>, _>>() 毎回乱数使ってるなら画面更新するたびにハッシュ変わるはずだよね?
https://play.rust-lang.org/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Ause%20std%3A%3Acollections%3A%3Ahash_map%3A%3ADefaultHasher%3B%0Ause%20std%3A%3Ahash%3A%3AHasher%3B%0A%0Alet%20mut%20hasher%20%3D%20DefaultHasher%3A%3Anew()%3B%0Alet%20data%20%3D%20%5B0x01%2C%200x23%2C%200x45%2C%200x67%2C%200x89%2C%200xab%2C%200xcd%2C%200xef%5D%3B%0A%0Ahasher.write(%26data)%3B%0A%0Aprintln!(%22Hash%20is%20%7B%3Ax%7D!%22%2C%20hasher.finish())%3B%0A%7D&edition=2018
変わらないよ? >>831
HashMapと同じことをしたいなら、RandomStateからbuild_hasherでhasherを得ればよい。別に画面更新しなくてもRUN押す度に変わるよ。 ちなみにDefaultHasher::newで変わらないのは、単に内部的にSipHasher13::new_with_keys(0,0)を呼んでるから。
RandomStateがその0,0をランダムに変えている。 Hash値の計算そのものも、本当はかなり速度が求められるものなので、それを
自在に変えるというのはどうやっているのか興味が有る。
Hash値そのものの計算は、遅いわけではないが、それでも膨大なデータを処理する
場合には、その問題になることがある。 SipHasher13::new_with_keys(0,0)はソルト?シード? >>830
えっ、それでいけたんだ……。
知らんかった。 collectが中でやってる事って std::convert::from か? >>839
FromIterator::from_iter呼んでる
From呼ばれるかどうかはFromIteratorの実相次第だけど
普通はIterator::Itemがそのままコレクションのデータ型になるから呼ばれないと思う これがコンパイルエラーになる(sum::<i64>()としないといけない)のってなんでですか?
let s: i64 = (0i64..10).sum() + 10i64;
推論できる材料は十分に見えるんですけども
ちなみにこれなら通ります
let s: i64 = (0..10).sum(); >>841
ここに理由書いてるけど、詳しくはわからん
At the moment, we always refuse to guess the "self" type, so we just stop there.
For other type parameters, if Self is known, we will sometimes infer them based on Self
https://github.com/rust-lang/rust/issues/25094#issuecomment-304079316 >>843
下位互換失うからじゃね?
>because it leads to regressions when new impls are added. ■ このスレッドは過去ログ倉庫に格納されています