[過去ログ]
Rust part24 (1002レス)
Rust part24 http://mevius.5ch.net/test/read.cgi/tech/1716759686/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
リロード規制
です。10分ほどで解除するので、
他のブラウザ
へ避難してください。
1: デフォルトの名無しさん [sage] 2024/05/27(月) 06:41:26.82 ID:T4AFD1f4 公式 https://www.rust-lang.org/ https://blog.rust-lang.org/ https://github.com/rust-lang/rust 公式ドキュメント https://www.rust-lang.org/learn Web上の実行環境 https://play.rust-lang.org ※Rustを学びたい人はまず最初に公式のThe Bookを読むこと https://doc.rust-lang.org/book/ ※Rustを学ぶ際に犯しがちな12の過ち https://dystroy.org/blog/how-not-to-learn-rust ※Rustのasyncについて知りたければ「async-book」は必読 https://rust-lang.github.io/async-book/ ※次スレは原則>>980が立てること 前スレ Rust part23 https://mevius.5ch.net/test/read.cgi/tech/1708677472/ http://mevius.5ch.net/test/read.cgi/tech/1716759686/1
876: デフォルトの名無しさん [sage] 2024/07/15(月) 18:49:44.14 ID:GgRIn2WF 独裁者にも見た目がダサい奴がよくいるけど言っても無駄だ デザインの力とは全然違う別の力でねじ伏せてくる http://mevius.5ch.net/test/read.cgi/tech/1716759686/876
877: デフォルトの名無しさん [] 2024/07/15(月) 19:16:07.61 ID:Vjas5sQD ダサいという指摘に理由を説明しても、ダサいことは変わらないんだよな 言語がダサければ信者もダサい うだうだ言いながらダサい服着てそう http://mevius.5ch.net/test/read.cgi/tech/1716759686/877
878: デフォルトの名無しさん [sage] 2024/07/15(月) 22:03:42.65 ID:e+J3OGv0 イテレータ要素をヒープに格納するにはこれでいいんか .fold(Vec::new(), |mut v, t| { v.push(t); v }) http://mevius.5ch.net/test/read.cgi/tech/1716759686/878
879: デフォルトの名無しさん [sage] 2024/07/15(月) 22:12:32.29 ID:S6UfnUI4 またイテレータの話してる http://mevius.5ch.net/test/read.cgi/tech/1716759686/879
880: デフォルトの名無しさん [sage] 2024/07/15(月) 22:50:12.36 ID:9YaXaz6n >>878 collectしろや http://mevius.5ch.net/test/read.cgi/tech/1716759686/880
881: デフォルトの名無しさん [] 2024/07/15(月) 23:25:29.58 ID:wT4qVw/w >>878 分かって書いてるかもだけど一応 let v = (0..10).collect::<Vec<i32>>(); コンテナにまとめるならこんな感じに collect を使う 例えば文字を走査するイテレーターをStringにcollectするようなことも可 型パラメーターは推論が効くのでそれに任せても良い 左辺に情報があるならcollectの型パラメーターはいらない let v: Vec<i32> = (0..10).collect(); 要素の型が分かるなら、右辺のコンテナの中身は_で推論させても良い let v = (0i32..10).collect::<Vec<_>>(); http://mevius.5ch.net/test/read.cgi/tech/1716759686/881
882: デフォルトの名無しさん [sage] 2024/07/15(月) 23:35:20.09 ID:nug4GWMJ クロージャにキャプチャさせれば既存ベクタへ格納も追加もできる let mut v = Vec::new(); iter.fold((), |_, t| v.push(t)); しかしこれではfold使ってる意味がなくこれと一緒 iter.for_each(|t| v.push(t)); もちろん正解は既存Vecへ追加なら v.extend(iter); 新規にVecへ収集なら let v = iter.collect::<Vec<_>>(); http://mevius.5ch.net/test/read.cgi/tech/1716759686/882
883: デフォルトの名無しさん [sage] 2024/07/16(火) 23:25:36.51 ID:ab19AXDr Foo::from_iter(iter)でもいいね 例えばVec::from_iter(iter) 特にIntoIteratorな時にinto_iter()を省けて見やすいよ http://mevius.5ch.net/test/read.cgi/tech/1716759686/883
884: デフォルトの名無しさん [sage] 2024/07/17(水) 18:51:22.39 ID:Hw1cPZyQ イテレータをcollectしたい場合と イテレータではないIntoIteratorを別の構造体に変換したい場合とは文脈が違うでしょ from_iterを直接呼ぶのは基本的に後者 前者の場合にターボフィッシュ書かなくてもいいという理由で from_iterを直接呼ぶのはidiomaticではない http://mevius.5ch.net/test/read.cgi/tech/1716759686/884
885: デフォルトの名無しさん [sage] 2024/07/17(水) 21:48:43.22 ID:3eay5eeN 前者のケースでfrom_iterを直接呼んでても分かるから別にいいよ 自分で書くときはcollect使うけど http://mevius.5ch.net/test/read.cgi/tech/1716759686/885
886: デフォルトの名無しさん [sage] 2024/07/17(水) 23:54:54.61 ID:zgRAxdKk これは短い方がいい let x = HashMap::<_, _>::from_iter(vec); let x = vec.into_iter().collect::<HashMap::<_, _>>(); http://mevius.5ch.net/test/read.cgi/tech/1716759686/886
887: デフォルトの名無しさん [sage] 2024/07/17(水) 23:55:29.92 ID:zgRAxdKk これはほぼ長さ変わらないからどちらがわかりやすいか let x = HashMap::<_, _>::from_iter(iter); let x = iter.collect::<HashMap::<_, _>>(); http://mevius.5ch.net/test/read.cgi/tech/1716759686/887
888: デフォルトの名無しさん [sage] 2024/07/18(木) 01:10:31.87 ID:CNIyJc+8 どちらも一度変数で受ける形になるので型アノテーションが必要なら let x: HashMap<_, _> のように基本的には左辺に書く HashMapなら型パラメータ部分も推論に頼らず 明示的に書くことのほうが多いかもしれない イテレータをcollectしたい場合というのは イテレータのメソッドチェーンで各種処理をしてから 最終的にcollectする形になることが多いから from_iterの直呼びじゃなくcollectが好まれる http://mevius.5ch.net/test/read.cgi/tech/1716759686/888
889: デフォルトの名無しさん [sage] 2024/07/18(木) 02:40:28.19 ID:0QBRSK+b ところでchronoって、しょっちゅうAPIが変わるし やたら冗長な書き方になるし結構クソじゃない? http://mevius.5ch.net/test/read.cgi/tech/1716759686/889
890: デフォルトの名無しさん [sage] 2024/07/18(木) 12:05:40.95 ID:WL/aeG4d 書き方が気に入らないならtime-rsを試してみたら? http://mevius.5ch.net/test/read.cgi/tech/1716759686/890
891: デフォルトの名無しさん [sage] 2024/07/18(木) 21:07:48.37 ID:2m7Ost/Q なるほど trait Iterator { type Item; fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized, { FromIterator::from_iter(self) } } http://mevius.5ch.net/test/read.cgi/tech/1716759686/891
892: デフォルトの名無しさん [sage] 2024/07/18(木) 23:31:33.62 ID:GQ1B8wHA 代数的データ型ってなんかすごいけど知名度がモナドより低いな http://mevius.5ch.net/test/read.cgi/tech/1716759686/892
893: デフォルトの名無しさん [sage] 2024/07/19(金) 02:03:52.09 ID:MUvBupZH >>890 使ってみたけど、time-rsいいね いつのまにかダウンロード数でchronoを上回る競合があったとは知らんかった タイムゾーンの扱いがやや簡略化されてるけど、夏時間のない日本人的には問題ない 月を直接intで指定できないのが英語仕様やな……ってちょっと気になる http://mevius.5ch.net/test/read.cgi/tech/1716759686/893
894: デフォルトの名無しさん [sage] 2024/07/19(金) 03:51:08.70 ID:riLGg6QV >>891 この各収納先への移譲と両側のトレイト境界が汎用化の肝 trait FromIterator<A>: Sized { fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self; } http://mevius.5ch.net/test/read.cgi/tech/1716759686/894
895: デフォルトの名無しさん [sage] 2024/07/19(金) 06:06:24.35 ID:LryDU6eW Rustはジェネリックとトレイト境界と抽象的なデフォルト実装のおかげで 安全で利便性の高いコードの汎用共通化に成功していますね http://mevius.5ch.net/test/read.cgi/tech/1716759686/895
896: デフォルトの名無しさん [] 2024/07/19(金) 23:21:36.34 ID:rC6z5NUh cloud strike のはテロルやね http://mevius.5ch.net/test/read.cgi/tech/1716759686/896
897: デフォルトの名無しさん [] 2024/07/19(金) 23:30:11.35 ID:rC6z5NUh >>886 let x; HashMap::<_, _> = vec.try_into()?; >>889 +1 http://mevius.5ch.net/test/read.cgi/tech/1716759686/897
898: デフォルトの名無しさん [sage] 2024/07/19(金) 23:52:20.75 ID:8WlCJE3Q >>897 エラーとなりますた http://mevius.5ch.net/test/read.cgi/tech/1716759686/898
899: デフォルトの名無しさん [sage] 2024/07/20(土) 00:12:48.41 ID:bNknJoN/ >>896 ウィルスバスター以来の快挙やね http://mevius.5ch.net/test/read.cgi/tech/1716759686/899
900: デフォルトの名無しさん [sage] 2024/07/20(土) 14:16:49.05 ID:F167yFzL >>898 ; が : の間違いかな >>899 暴落予想 note.com/asset_n_ichi/n/nceaa6f318b1e http://mevius.5ch.net/test/read.cgi/tech/1716759686/900
901: デフォルトの名無しさん [sage] 2024/07/20(土) 23:38:20.92 ID:6EAP68vq >>897 HashMapとVecにTryFromが実装されていないから無理 FromIteratorが実装されているのでそれを使う http://mevius.5ch.net/test/read.cgi/tech/1716759686/901
902: デフォルトの名無しさん [sage] 2024/07/21(日) 01:48:23.56 ID:eUhj6//q ★┷┓ ┃D┃ ┃D┃ ┃K┃ ┃で┃ ┃も┃ ┃r┃ ┃u┃ ┃s┃ ┃t┃ ┃が┃ ┃使┃ ┃え┃ ┃ま┃ ┃す┃ ┃よ┃ ┃う┃ ┃に┃ ┗━★ http://mevius.5ch.net/test/read.cgi/tech/1716759686/902
903: デフォルトの名無しさん [sage] 2024/07/21(日) 09:43:03.00 ID:QhoywuRk >>901 こういうのが「Rustは学習コストが高い」って言われる原因なんだろうな 答えを知ってる人は判ってても答えを知らない人は判らない 答えを調べるのにコストがかかりすぎる http://mevius.5ch.net/test/read.cgi/tech/1716759686/903
904: デフォルトの名無しさん [sage] 2024/07/21(日) 10:14:17.60 ID:TGGT0XLq とあるライブラリに変な癖があるという話は どの言語でもあるからそういう話ではないだろ http://mevius.5ch.net/test/read.cgi/tech/1716759686/904
905: デフォルトの名無しさん [sage] 2024/07/21(日) 10:29:10.85 ID:U3c7smqS イテレータ使ったことない http://mevius.5ch.net/test/read.cgi/tech/1716759686/905
906: デフォルトの名無しさん [sage] 2024/07/21(日) 10:35:28.58 ID:W0nR4Dwz >>903 Rustはその点シンプルでクセもなく覚えやすい 基本的に複数の要素ならFromIterator VecでもHashMapでも何でもいける 複数のcharやstrなどからString作成もいける 複数のstrやStringやPathなどからPathBuf作成もいける Fromは基本的に単独要素や配列(=静的固定長)から他へ変換 http://mevius.5ch.net/test/read.cgi/tech/1716759686/906
907: デフォルトの名無しさん [sage] 2024/07/21(日) 11:03:59.33 ID:BMrg5vDt >>903 >>897のはコンパイルエラーの内容が読めればすぐわかる エラーの内容が読める程度の基礎力は最初に勉強して身につける必要がある そもそもtry_intoでどういうケースならエラーにして欲しいのか考えればおかしいことに気付く サードパーティライブラリの学習コストは他の言語に比べると顕著に高いが 基本的な言語機能や標準ライブラリは言うほど高くない JavaやC#あたりと比べるとむしろ学習コスト低いんじゃないかと思う http://mevius.5ch.net/test/read.cgi/tech/1716759686/907
908: デフォルトの名無しさん [] 2024/07/21(日) 11:04:04.35 ID:xuKRyHnL >>903 それくらいchatGPTで教えてもらえるだろ http://mevius.5ch.net/test/read.cgi/tech/1716759686/908
909: デフォルトの名無しさん [sage] 2024/07/21(日) 11:14:46.17 ID:BMrg5vDt >>908 俺もそう思って試してみたけど駄目だね エラーの簡単な原因とcollect使えみたいな代替案は出してくるけど 根本的な理解につながる答えを返せないだけでなくいろいろと間違った情報を返してくる http://mevius.5ch.net/test/read.cgi/tech/1716759686/909
910: デフォルトの名無しさん [sage] 2024/07/21(日) 11:48:09.12 ID:W0nR4Dwz from_iter(array)で済むのに なぜ配列からHashMapへのFromがあるのか理由はおそらく 配列からmoveするinto_iter()が数年前までなかったためだと思う 今は配列を含めて要素が複数なら→イテレータ利用→FromIteratorと覚えればよいかと http://mevius.5ch.net/test/read.cgi/tech/1716759686/910
911: デフォルトの名無しさん [] 2024/07/21(日) 11:54:05.33 ID:9I2odrUJ そもそもイテレーターとコンテナの概念を勘違いしてる可能性ありそう 別種のコンテナ同士の変換は (特別な対応がない限り) 直接的には無理で、イテレーターを介して中身の要素を走査すれば渡せるということ みかん箱を冷蔵庫に変換することはできないけど、箱の中のみかんを1つずつ取り出して、それを冷蔵庫型に纏める (collect) ことはできるような感じ http://mevius.5ch.net/test/read.cgi/tech/1716759686/911
912: デフォルトの名無しさん [sage] 2024/07/21(日) 12:08:53.38 ID:QhoywuRk 今回は >>910 さんをベストアンサーとさせて頂きます みなさんご協力ありがとうございました http://mevius.5ch.net/test/read.cgi/tech/1716759686/912
913: デフォルトの名無しさん [sage] 2024/07/21(日) 12:17:32.86 ID:rbHgMj6q >>911 それは単に抽象度の違いであって勘違いでも何でもない http://mevius.5ch.net/test/read.cgi/tech/1716759686/913
914: デフォルトの名無しさん [sage] 2024/07/21(日) 12:17:32.92 ID:QhoywuRk >>911 勘違いはしてない use std::collections::HashMap; use std::iter::FromIterator; fn main() { let u = vec![("hoge", 1), ("fuga", 2)]; let x: HashMap::<_, _> = u.into_iter().collect(); println!("{:?}", x); let v = vec![("hoge", 1), ("fuga", 2)]; let y = HashMap::<_, _>::from_iter(v); // use std::iter::FromIterator println!("{:?}", y); let w = [("hoge", 1), ("fuga", 2)]; // array let z = HashMap::<_, _>::from(w); println!("{:?}", z); } http://mevius.5ch.net/test/read.cgi/tech/1716759686/914
915: デフォルトの名無しさん [sage] 2024/07/21(日) 12:21:47.94 ID:QhoywuRk なぜ Vec から HashMap は from が使えないのか? の問いに GPT は答えてくれない http://mevius.5ch.net/test/read.cgi/tech/1716759686/915
916: デフォルトの名無しさん [sage] 2024/07/21(日) 12:29:53.31 ID:+gih9iRs >>910 順番が逆 arrayにIntoIteratorが実装された方が先で From array for HashMapのほうが後 http://mevius.5ch.net/test/read.cgi/tech/1716759686/916
917: デフォルトの名無しさん [sage] 2024/07/21(日) 12:32:17.29 ID:BMrg5vDt >>915 そこはFromのimplがないからと答えてくれる coherenceの制約を先回りして答えてくれるかどうかは質問次第 http://mevius.5ch.net/test/read.cgi/tech/1716759686/917
918: デフォルトの名無しさん [sage] 2024/07/21(日) 13:57:28.77 ID:W0nR4Dwz >>916 ありがと 調べたらその順だね そうなるとFrom<配列>だけを特別に用意した理由は配列が基本型だからだろうか HashMap::from(array)のコードを見ると HashMap::from_iter(array)とFromIteratorの実装を呼び出すだけなので http://mevius.5ch.net/test/read.cgi/tech/1716759686/918
919: デフォルトの名無しさん [sage] 2024/07/21(日) 16:06:46.61 ID:nMuf3u03 MapやSetのリテラルがないけどリテラルに近い感覚で初期化したい場合の代替策として用意されたのがFromの実装 http://mevius.5ch.net/test/read.cgi/tech/1716759686/919
920: デフォルトの名無しさん [sage] 2024/07/21(日) 16:20:17.13 ID:BJsLblxy _iterの5文字が節約できるメリットだけか http://mevius.5ch.net/test/read.cgi/tech/1716759686/920
921: デフォルトの名無しさん [sage] 2024/07/21(日) 16:39:36.83 ID:u5tRysNp >>920 タイプアノテーションの要不要があるのでもっと節約できるよ http://mevius.5ch.net/test/read.cgi/tech/1716759686/921
922: デフォルトの名無しさん [sage] 2024/07/21(日) 16:43:19.24 ID:BJsLblxy >>921 不要になる例を出して http://mevius.5ch.net/test/read.cgi/tech/1716759686/922
923: デフォルトの名無しさん [sage] 2024/07/21(日) 17:05:45.63 ID:QAZ3DYjh FromがあるとIntoが使えるからHashMap返すときとか引数で渡すときに HashMap::from([..]) の代わりに [..].into() で書ける 型を明記するletだと大差ないかも let map: HashMap<K, V> = [..].into(); let map = HashMap::<K, V>::from([..]); http://mevius.5ch.net/test/read.cgi/tech/1716759686/923
924: デフォルトの名無しさん [sage] 2024/07/21(日) 17:22:33.98 ID:BJsLblxy >>923 そこでタイプアノテーションが不要になる例はないよな 関数の引数型か返り型に書いている into()と書ける件も collect()と書けるから FromIteratorに対してFromもあるメリットは3文字節約できるだけか http://mevius.5ch.net/test/read.cgi/tech/1716759686/924
925: デフォルトの名無しさん [sage] 2024/07/21(日) 21:02:32.72 ID:eUhj6//q dyn traits以外にinto使うなよ。変換するんだから let s = "Hello, world!"; let string = Into::<String>::into(s); じゃなくて let s = "Hello, world!"; let string = String::form(s); だろ。 http://mevius.5ch.net/test/read.cgi/tech/1716759686/925
926: デフォルトの名無しさん [sage] 2024/07/21(日) 21:07:32.49 ID:BUmQiTHC は? http://mevius.5ch.net/test/read.cgi/tech/1716759686/926
927: デフォルトの名無しさん [sage] 2024/07/21(日) 22:10:59.79 ID:kEjkNYpd >>922 use std::collections::HashMap; fn main() { let xs = [(1, "a"), (2, "b"), (3, "c")]; let map = HashMap::from(xs); println!("{:?}", map); } http://mevius.5ch.net/test/read.cgi/tech/1716759686/927
928: デフォルトの名無しさん [sage] 2024/07/21(日) 22:23:54.17 ID:vNf5wQaP >>927 HashMap::from_iter(xs)で十分じゃね http://mevius.5ch.net/test/read.cgi/tech/1716759686/928
929: デフォルトの名無しさん [sage] 2024/07/21(日) 22:30:45.10 ID:kEjkNYpd >>928 error[E0283]: type annotations needed for `HashMap<i32, &str, _>` --> src/main.rs:5:9 | 5 | let map = HashMap::from_iter(xs); | ^^^ ------- type must be known at this point | http://mevius.5ch.net/test/read.cgi/tech/1716759686/929
930: デフォルトの名無しさん [sage] 2024/07/22(月) 12:16:14.88 ID:7a9cZObY 配列からのFromは機能が制限されている struct HashMap<K, V, S = RandomState> { ... } impl<K: Eq + Hash, V, S: BuildHasher + Default> FromIterator<(K, V)> for HashMap<K, V, S> { ... } impl<K: Eq + Hash, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState> { ... } http://mevius.5ch.net/test/read.cgi/tech/1716759686/930
931: デフォルトの名無しさん [sage] 2024/07/22(月) 12:18:01.98 ID:7a9cZObY つまりFromは重いデフォルトハッシャーに固定されてしまっている FromIteratorを使えば自由に速いものを利用できる let xxx = HashMap::<_, _, FxHash>::from_iter(array); http://mevius.5ch.net/test/read.cgi/tech/1716759686/931
932: デフォルトの名無しさん [sage] 2024/07/23(火) 01:07:15.84 ID:XvQFw5Nb HashMap::from(配列)の場合は デフォルトハッシャーで困るユースケースは稀だから APIのエルゴノミクスのために意図的にRandomStateに固定してる そのおかけでタイプアノテーションなしで書ける タイプアノテーション無しの場合はデフォルト指定の型を優先的に使うよう Rustのコンパイラが改良されればこの辺の差はなくなる http://mevius.5ch.net/test/read.cgi/tech/1716759686/932
933: デフォルトの名無しさん [sage] 2024/07/23(火) 01:10:26.97 ID:XvQFw5Nb >>931 >let xxx = HashMap::<_, _, FxHash>::from_iter(array); FxHashのところはFxBuildHasherだね let xxx = FxHashMap::from_iter(array);と書いたほうがいろいろ親切 親切設計のライブラリなら let xxx = AHashMap::from(array); のようにFromIteratorだけでなくFromも使える http://mevius.5ch.net/test/read.cgi/tech/1716759686/933
934: デフォルトの名無しさん [] 2024/07/23(火) 01:31:49.01 ID:Rfg4Mjqa tupleをiteratorしたいんだが無理? http://mevius.5ch.net/test/read.cgi/tech/1716759686/934
935: デフォルトの名無しさん [sage] 2024/07/23(火) 02:50:50.92 ID:l+hNtTPE こういう意味? let t = ("abcde", "fghijkl", "mno", "pqrstuvw", "xyz"); assert_eq!("abcdefghijklmnopqrstuvwxyz", Into::<[_; 5]>::into(t).into_iter().collect::<String>()); http://mevius.5ch.net/test/read.cgi/tech/1716759686/935
936: デフォルトの名無しさん [sage] 2024/07/23(火) 09:22:40.63 ID:iSDzXJU2 同じ型だけの要素で構成されるtupleならいけそうだけど 色んな型ば混ざってるtupleはエラー出そう http://mevius.5ch.net/test/read.cgi/tech/1716759686/936
937: デフォルトの名無しさん [sage] 2024/07/23(火) 11:25:10.18 ID:ijWLrFq+ dynにすれば色んな型を混ぜられる 関数から返すときはBox<dyn ...>にする 例えば数値と文字列が混じる有名な例をRustでdynを使って書くと type FizzBuzz = Box<dyn std::fmt::Display>; fn fizz_buzz_iter() -> impl Iterator<Item=FizzBuzz> { (1..).map(|int| match (int % 3, int % 5) { (0, 0) => Box::new("FizzBuzz") as FizzBuzz, (0, _) => Box::new("Fizz"), (_, 0) => Box::new("Buzz"), (_, _) => Box::new(int), }) } fn main() { for x in fizz_buzz_iter().take(30) { println!("{x}"); } } http://mevius.5ch.net/test/read.cgi/tech/1716759686/937
938: デフォルトの名無しさん [sage] 2024/07/23(火) 17:24:06.93 ID:hqmWVJB3 またFizzBuzzイテレータ書いてる…… http://mevius.5ch.net/test/read.cgi/tech/1716759686/938
939: デフォルトの名無しさん [] 2024/07/23(火) 21:36:57.26 ID:1jhTJKzb >>936 Haskellだとタプルって構造体代わりだから、色んな型が混ざってる方が普通だけど…。 (ともすれば関数も入れるし。同じ型だけってのはリストのイメージ) Rustじゃ用途違うん? http://mevius.5ch.net/test/read.cgi/tech/1716759686/939
940: デフォルトの名無しさん [sage] 2024/07/23(火) 21:58:12.50 ID:joaeWjir タプルは型の制限なくバラバラでいいよ 今回はそれを>>934「iteratorしたい」なので 同じ型に揃えるためにdynかenumを使う http://mevius.5ch.net/test/read.cgi/tech/1716759686/940
941: デフォルトの名無しさん [sage] 2024/07/23(火) 23:07:54.81 ID:tKFzmUCx ほとんどの言語でオブジェクトを返す時にヒープを使うから RustでもBox<dyn>を使っても構わないけど ライフタイムさえ満たしてやればヒープを使わずに&dynにできるよ use std::fmt::Display; type FizzBuzz<'a> = &'a dyn Display; fn fizz_buzz_iter<'a, T: Display>(i: &'a[T], s: &'a[&str; 3]) -> impl Iterator<Item = FizzBuzz<'a>> { (1..).map_while(|int| match (int % 3, int % 5) { (0, 0) => Some(&s[0] as FizzBuzz), (0, _) => Some(&s[1]), (_, 0) => Some(&s[2]), (_, _) => i.get(int).map(|int| int as FizzBuzz), }) } fn main() { let i: [_; 256] = std::array::from_fn(|i| i as u8); let s: [_; 3] = ["FizzBuzz", "Fizz", "Buzz"]; for x in fizz_buzz_iter(&i, &s).take(30) { println!("{x}"); } } http://mevius.5ch.net/test/read.cgi/tech/1716759686/941
942: デフォルトの名無しさん [] 2024/07/23(火) 23:38:39.26 ID:QoNSkCmh 「tupleでイテレートできないの?」という質問に「こういうイテレータなら異なる型を混ぜられるよ」と回答するあたりがいかにもな感じ 率直に「できる/できない」で回答した上で補足として書けばいいのに http://mevius.5ch.net/test/read.cgi/tech/1716759686/942
943: デフォルトの名無しさん [sage] 2024/07/23(火) 23:40:03.74 ID:38zrS1+w トレイトオブジェクトをdynと呼ぶのは複オジだけ http://mevius.5ch.net/test/read.cgi/tech/1716759686/943
944: デフォルトの名無しさん [sage] 2024/07/23(火) 23:40:30.32 ID:38zrS1+w >>942 それな http://mevius.5ch.net/test/read.cgi/tech/1716759686/944
945: デフォルトの名無しさん [sage] 2024/07/23(火) 23:49:18.56 ID:lLea54if Rust 2018 editionからdyn必須に変わった http://mevius.5ch.net/test/read.cgi/tech/1716759686/945
946: デフォルトの名無しさん [sage] 2024/07/24(水) 00:02:23.05 ID:QMkBbV1F できる/できないで言えばできるよ タプルの要素がすべて同じ型で要素数が12個以内ならFrom/Intoで配列に変換してイテレートする それ以外ならextension traitで自前のイテレータを返すメソッドをタプルに実装する 他にも方法あるけどこの2つが主 タプルの型・要素数、イテレート時の型を汎用化したい場合はマクロが必須でそこそこめんどくさい 特にヘテロなタプルを汎用的にイテレート用の型に揃えるのはめんどくさい 本当にタプルで管理するのが望ましいのか タプルで管理しつつイテレータで回すのがベストなのか まずはよく考えたほうがいいと思う http://mevius.5ch.net/test/read.cgi/tech/1716759686/946
947: デフォルトの名無しさん [sage] 2024/07/24(水) 00:15:33.28 ID:sAqPevwn dynを使えば型が何種類でもいけてトレイト境界も使えて楽だろうけどdynは重い Fizz Buzzのように2種類の型で済むならEitherを使う 色んなトレイトを透過的に対応してくれている use either::Either::{self, Left, Right}; type FizzBuzz = Either<usize, &'static str>; fn fizz_buzz_iter() -> impl Iterator<Item = FizzBuzz> { (1..).map(|int| match (int % 3, int % 5) { (0, 0) => Right("FizzBuzz"), (0, _) => Right("Fizz"), (_, 0) => Right("Buzz"), (_, _) => Left(int), }) } http://mevius.5ch.net/test/read.cgi/tech/1716759686/947
948: デフォルトの名無しさん [sage] 2024/07/24(水) 00:35:21.34 ID:UKniupNy リフレクションのサポートとかにもっと力入れてれば普通にできるんだろうけど、しゃあなし Rustはそういうの好かない言語だから http://mevius.5ch.net/test/read.cgi/tech/1716759686/948
949: 警備員[Lv.2][新芽] [sage] 2024/07/24(水) 00:44:54.58 ID:djH/Nw1D rustって流行るかな http://mevius.5ch.net/test/read.cgi/tech/1716759686/949
950: デフォルトの名無しさん [] 2024/07/24(水) 03:12:39.74 ID:s3z853Sv >>940 タプルをイテレーションしたい…。 リストとか、配列みたいに使いってことですよね? Haskellでは無理ですが、Rustでは可能なのでしょうか? (構造体代わりと言った通り、構造体をイテレーションしようと思わないですよね?) Python,RubyのリストとHaskellのそれみたいに、そもそもの意味が違う可能性もありますし…。 http://mevius.5ch.net/test/read.cgi/tech/1716759686/950
951: デフォルトの名無しさん [] 2024/07/24(水) 03:25:04.27 ID:sCVmnNU/ >>935 let t = ("abcde", 123, "mno", "pqrstuvw", 456); for e Into::<[_; 5]>::into(t).into_iter() { println!("{:?}", e) } 無理ポorz http://mevius.5ch.net/test/read.cgi/tech/1716759686/951
952: デフォルトの名無しさん [] 2024/07/24(水) 03:30:03.16 ID:sCVmnNU/ >>946 それっぽいクレートがあるけどよう判らん これはどんな感じ? https://crates.io/crates/tuple-iter http://mevius.5ch.net/test/read.cgi/tech/1716759686/952
953: デフォルトの名無しさん [sage] 2024/07/24(水) 03:57:10.87 ID:yTLgnmif これは典型的なXY問題だから相手にするだけ無駄 質問者は本当に解決したい元の課題Xを素直に話すべき 自分の思い込みで勝手に判断して進めた二次的な課題Yについて質問しているからそれについては相手にしなくていい http://mevius.5ch.net/test/read.cgi/tech/1716759686/953
954: デフォルトの名無しさん [sage] 2024/07/24(水) 04:42:12.08 ID:sCVmnNU/ >>946 imple IntoIterator for (&str, u64, &str, &str, u64) { ... } で出来るかと思ったけど this is not defined in the current crate because tuples are always foreign http://mevius.5ch.net/test/read.cgi/tech/1716759686/954
955: デフォルトの名無しさん [sage] 2024/07/24(水) 05:38:42.31 ID:U0F2g2Py dynやenumにしろと本質的なアドバイスをもらえているのに対応しようとしない人 http://mevius.5ch.net/test/read.cgi/tech/1716759686/955
956: デフォルトの名無しさん [sage] 2024/07/24(水) 07:25:15.81 ID:Py4dd1Kh たしかにXY問題だな 「異なる型が入り乱れてイテレートしたい」←何のために? 「異なる型が入り乱れてタプルがある」←どうやってそれが出来た? http://mevius.5ch.net/test/read.cgi/tech/1716759686/956
957: デフォルトの名無しさん [] 2024/07/24(水) 08:43:52.20 ID:NUYI7xpt ・タプルは型を混合できる ・タプルはイテレートできない ・異なる型でのイテレートがしたいなら、タプルの代わりに Box<dyn Trait> のような動的型かenum (直和型) の配列を使う で良いんじゃない? http://mevius.5ch.net/test/read.cgi/tech/1716759686/957
958: デフォルトの名無しさん [sage] 2024/07/24(水) 08:43:57.79 ID:sCVmnNU/ とりあえず出来ました struct Hoge<'a> { t: (&str, u64, &str, &str, u64) } impl<'a> IntoIterator for Hoge<'a> { type Item = Fuga<'a>; type IntoIter = std::vec::IntoIter<Self::Item>; fn into_iter(self) -> Self::IntoIter { vec![ Fuga::from(self.t.0), Fuga::from(self.t.1), Fuga::from(self.t.2), Fuga::from(self.t.3), Fuga::from(self.t.4), ].into_iter() } } みなさんありがとうございました http://mevius.5ch.net/test/read.cgi/tech/1716759686/958
959: デフォルトの名無しさん [] 2024/07/24(水) 08:50:34.05 ID:NUYI7xpt XY問題だとか言うけど、上のFizzBuzイテレーターなんかはXとYのどちらとも関係ないでしょ 既にあるデータに対してイテレートする方法でなく、FizzBuzを0から生成するだけだから それをしつこく何度も書くあたりが本物 http://mevius.5ch.net/test/read.cgi/tech/1716759686/959
960: デフォルトの名無しさん [sage] 2024/07/24(水) 09:24:46.95 ID:eaHzhPzb >>959 それな http://mevius.5ch.net/test/read.cgi/tech/1716759686/960
961: デフォルトの名無しさん [sage] 2024/07/24(水) 09:30:08.78 ID:+W2StRcH 意味のないFizzBuzzを散々書いておいて答えられなくなったら急に質問者を攻撃する複オジくん草 http://mevius.5ch.net/test/read.cgi/tech/1716759686/961
962: デフォルトの名無しさん [sage] 2024/07/24(水) 12:35:19.94 ID:qFVR7Ywl 必要な個数のタプルを配列に変換するコードでいいんじゃないかな これは長さ自由に機械的にマクロで生成できそう struct Wrapper<A, B, C, D, E>((A, B, C, D, E)); impl<A, B, C, D, E> From<Wrapper<A, B, C, D, E>> for [Tx; 5] where Tx: From<A> + From<B> + From<C> + From<D> + From<E>, { fn from(x: Wrapper<A, B, C, D, E>) -> Self { [Tx::from(x.0.0), Tx::from(x.0.1), Tx::from(x.0.2), Tx::from(x.0.3), Tx::from(x.0.4)] } } impl<A, B, C, D, E> IntoIterator for Wrapper<A, B, C, D, E> where Tx: From<A> + From<B> + From<C> + From<D> + From<E>, { type Item = Tx; type IntoIter = std::array::IntoIter<Self::Item, 5>; fn into_iter(self) -> Self::IntoIter { let x: [Self::Item; 5] = self.into(); x.into_iter() } } http://mevius.5ch.net/test/read.cgi/tech/1716759686/962
963: デフォルトの名無しさん [sage] 2024/07/24(水) 12:36:33.67 ID:qFVR7Ywl あとはタプルに登場する型を列挙して 例えばこんなコードを機械的に自動生成させてしまえばいいね type T1 = &'static str; type T2 = i64; type T3 = f64; enum Tx { T1(T1), T2(T2), T3(T3), } impl From<T1> for Tx { fn from(x: T1) -> Self { Self::T1(x) } } impl From<T2> for Tx { fn from(x: T2) -> Self { Self::T2(x) } } impl From<T3> for Tx { fn from(x: T3) -> Self { Self::T3(x) } } impl std::fmt::Display for Tx { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Self::T1(x) => write!(f, "{x}"), Self::T2(x) => write!(f, "{x}"), Self::T3(x) => write!(f, "{x}"), } } } http://mevius.5ch.net/test/read.cgi/tech/1716759686/963
964: デフォルトの名無しさん [sage] 2024/07/24(水) 12:38:12.03 ID:qFVR7Ywl そうするとタプルの中の型の順番は任意でよくて タプルをラッパーにかませるだけで利用できるよ fn main() { let tuple = ("abcde", 123, "nop", 0.456, 789); for x in Wrapper(tuple) { println!("{x}"); } for (i, x) in Wrapper((-1, "pi", 3, 3.14159, "END")).into_iter().enumerate() { println!("{i}: {x}"); } } http://mevius.5ch.net/test/read.cgi/tech/1716759686/964
965: デフォルトの名無しさん [sage] 2024/07/24(水) 12:43:52.56 ID:mjGiit/q 効いてる効いてるw http://mevius.5ch.net/test/read.cgi/tech/1716759686/965
966: デフォルトの名無しさん [sage] 2024/07/24(水) 12:49:36.37 ID:TJmYfYAi 「XY問題だから相手にするだけ無駄」と言い放っておいてからの〜〜 http://mevius.5ch.net/test/read.cgi/tech/1716759686/966
967: デフォルトの名無しさん [sage] 2024/07/24(水) 17:04:11.48 ID:1Kw3Uuff もっと建設的な話題はないの? http://mevius.5ch.net/test/read.cgi/tech/1716759686/967
968: デフォルトの名無しさん [sage] 2024/07/24(水) 19:14:00.84 ID:UKniupNy 5chより建設的なコミュニティを列挙し移住を検討するのが目下最も建設的な話題である http://mevius.5ch.net/test/read.cgi/tech/1716759686/968
969: デフォルトの名無しさん [] 2024/07/24(水) 21:00:33.77 ID:bzm5y73f 最近出た便利クレートの話とかすれば良いんじゃね? http://mevius.5ch.net/test/read.cgi/tech/1716759686/969
970: デフォルトの名無しさん [sage] 2024/07/24(水) 22:25:44.31 ID:mF9Tvkg9 ベストな日付処理クレートについて議論しよう http://mevius.5ch.net/test/read.cgi/tech/1716759686/970
971: デフォルトの名無しさん [sage] 2024/07/25(木) 08:45:26.25 ID:q/t9CUhu おすすめクレートの話はしてほしいな~ http://mevius.5ch.net/test/read.cgi/tech/1716759686/971
972: デフォルトの名無しさん [sage] 2024/07/25(木) 10:09:56.78 ID:P+cFrEvf クレートの話をしてくれー、と http://mevius.5ch.net/test/read.cgi/tech/1716759686/972
973: デフォルトの名無しさん [] 2024/07/25(木) 22:41:22.06 ID:zdgCFOr2 クレートではないけれど今日リリースのRust 1.80でLazyCell, LazyLockが安定版に入ったよ グローバルな変数を外部クレート無しで書きやすくなる http://mevius.5ch.net/test/read.cgi/tech/1716759686/973
974: デフォルトの名無しさん [sage] 2024/07/25(木) 22:49:30.69 ID:9YYk7vP+ >>973 それ、OnceCell使ってたコードは全部置き換えた方がいい奴? http://mevius.5ch.net/test/read.cgi/tech/1716759686/974
975: デフォルトの名無しさん [] 2024/07/25(木) 23:18:37.32 ID:zdgCFOr2 >>974 自分はそれを言えるほど詳しくないけど、必ずしも必要ではないと思う 依存クレートを減らせる点で嬉しいし、今から書くコードでは新しいものにして良いと思うけど、今使ってるものをすぐに置き換える必要があるとまでは思わない 特にライブラリを作ってる場合は、rustcを今日リリースされたばかりの最新バージョンに上げないとライブラリをビルドできなくなるということなので、もう少し待った方が良いかもしれない http://mevius.5ch.net/test/read.cgi/tech/1716759686/975
976: デフォルトの名無しさん [sage] 2024/07/26(金) 00:25:09.02 ID:/65SSmn2 OnceLockからLazyLockへ移行すると 変数宣言と初期化関数が離れていた可読性の問題が解決するとともに 例えばget_or_initを一箇所にするために一つ関数を用意したりするなどしていた手間も省けるようになるね そして何よりも最大のメリットはDerefによりアクセスできる利便性 http://mevius.5ch.net/test/read.cgi/tech/1716759686/976
977: デフォルトの名無しさん [sage] 2024/07/26(金) 23:32:15.42 ID:/65SSmn2 とりあえず定番のこのあたりを置き換えた static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new("...").unwrap()); static SE: LazyLock<Selector> = LazyLock::new(|| Selector::parse("...").unwrap()); http://mevius.5ch.net/test/read.cgi/tech/1716759686/977
978: デフォルトの名無しさん [sage] 2024/07/27(土) 11:02:49.38 ID:WfV9QQMJ LazyLockよさそうね http://mevius.5ch.net/test/read.cgi/tech/1716759686/978
979: デフォルトの名無しさん [sage] 2024/07/27(土) 18:38:25.11 ID:U5WpGSyZ 俺の今日のハマりポイントを紹介 bindgenにC++のコンストラクタを作らせると、データが壊れる よく調べたら公式ドキュメントのConstructor semanticsに書いてあった https://rust-lang.github.io/rust-bindgen/cpp.html コンストラクタを抜けたとき、C++とちがってRustは値をムーブしちゃうので struct内部を参照したポインタが変なところを参照してバグる http://mevius.5ch.net/test/read.cgi/tech/1716759686/979
980: デフォルトの名無しさん [] 2024/07/27(土) 19:30:58.99 ID:s18eFGvS C++も部分的に使えるとはいえ、FFIするならCのAPIにしておく方が無難な気はする http://mevius.5ch.net/test/read.cgi/tech/1716759686/980
981: デフォルトの名無しさん [sage] 2024/07/27(土) 20:04:50.53 ID:U5WpGSyZ >>980 bindgenはFirefoxがプロダクトでたくさん使ってるって聞いて、いけると思ったんだ Firefoxは大半がC++だから http://mevius.5ch.net/test/read.cgi/tech/1716759686/981
982: デフォルトの名無しさん [] 2024/07/28(日) 15:27:45.35 ID:v6kdbv5j >>978 LazyLockさようなら に観えた http://mevius.5ch.net/test/read.cgi/tech/1716759686/982
983: デフォルトの名無しさん [sage] 2024/07/28(日) 15:29:40.57 ID:v6kdbv5j >>979 RustとC++は相性最悪 RustとCは相性良いバッチリ http://mevius.5ch.net/test/read.cgi/tech/1716759686/983
984: デフォルトの名無しさん [sage] 2024/07/30(火) 01:24:35.90 ID:xgbf/AIH >>979 この件って、RustはC++と比べて無駄にムーブするから遅いってこと? http://mevius.5ch.net/test/read.cgi/tech/1716759686/984
985: デフォルトの名無しさん [sage] 2024/07/30(火) 06:04:09.29 ID:RHAjweCG 無駄な移動は消える cargo asmで生成コードを見ることでそれを確認できる 移動前と移動後のアドレスを表示させて最適化を阻害することで元は別々となる例も確認できる http://mevius.5ch.net/test/read.cgi/tech/1716759686/985
986: デフォルトの名無しさん [] 2024/07/30(火) 12:06:12.26 ID:tiWzrJ23 >>984 >コンストラクタを抜けたとき、C++とちがってRustは値をムーブしちゃうので >struct内部を参照したポインタが変なところを参照してバグる って書いてるのに、読解力無い人? http://mevius.5ch.net/test/read.cgi/tech/1716759686/986
987: デフォルトの名無しさん [sage] 2024/07/30(火) 19:02:27.28 ID:dzXOiSL/ >>985 移動じゃなくてムーブね ここまでのレスで使われてる述語を踏襲すればいいよ http://mevius.5ch.net/test/read.cgi/tech/1716759686/987
988: デフォルトの名無しさん [sage] 2024/07/30(火) 20:13:33.28 ID:VUdF4pDl >>985 最適化のかかり具合でバグが消えたり現れたりする嫌なパターンだな http://mevius.5ch.net/test/read.cgi/tech/1716759686/988
989: デフォルトの名無しさん [sage] 2024/07/30(火) 20:41:43.84 ID:+5mpqNgW >>986 Rustを使えばそんなバグは起きない 参照のライフタイムは参照先より長くなることがコンパイル時点で保証される >>988 Rustならばそこでバグは起きようがない http://mevius.5ch.net/test/read.cgi/tech/1716759686/989
990: デフォルトの名無しさん [] 2024/07/30(火) 22:41:22.15 ID:GjQxUZ/0 >>989 本人じゃないのに出しゃばらせて頂きますが…。 Rust単体じゃなくて、C++との相性問題ですよ。相性最悪って書いてるんだから。 起きようがないじゃなくて、実際に起きてるらしいじゃないですか。 最適化で治るのなら大したことじゃなくても、デバッグ時にハマるの確実な類のバグ。 将来的に全部Rustで書けば起きないような問題も、過渡期の今は良く起きます。 「Rustを使えば」「Rustなら」。 そうでしょうけど、実際問題ライブラリがなければ既存のC/C++ライブラリ使う場面は多々あるでしょう。 (枯れたライブラリならなおさら) これはRustに限らず、後続の言語全てが抱えている問題です。 http://mevius.5ch.net/test/read.cgi/tech/1716759686/990
991: デフォルトの名無しさん [] 2024/07/30(火) 22:49:06.91 ID:MqLM+D1V 最適化じゃなくて単に移動の問題 Box::newで要素を直接ヒープに作れない (いちどスタックに作られてからコピーされる) のと同じで、コンストラクタを抜ける前に構造体が maybeuninit::assume_init で移動する その上で構造体のアドレスがC++のメソッドにthisポインタとして渡される際に問題を引き起こす、というように思える だとすると最適化の有無は関係なく起こる気がする ついでにいえば >>987 もあまり意味のない発言で、移動はムーブの訳語でもある (例えばC++の仕様の訳語に移動コンストラクタという表現がある) し、そもそもこの問題はムーブセマンティクスによるものでもない これはStringやVecが持つリソースを所有権ごと移動することで効率的に別の変数に割り当てるもので、構造体のアドレスのようなローレベルなものとは違うかと http://mevius.5ch.net/test/read.cgi/tech/1716759686/991
992: デフォルトの名無しさん [] 2024/07/30(火) 22:59:00.85 ID:MqLM+D1V 移動とムーブが仕様として別物だというなら、移動は英語でどう表現されてるんだ? http://mevius.5ch.net/test/read.cgi/tech/1716759686/992
993: デフォルトの名無しさん [sage] 2024/07/30(火) 23:00:06.83 ID:L/ylOhaJ >>990 それはRust単体では全く発生しない問題だね C++とRustを併用する時にRustの知識を持たない人がハマるという話 FFI部分は両者の概念と挙動の違いの知識を持った人が作るべきだね http://mevius.5ch.net/test/read.cgi/tech/1716759686/993
994: デフォルトの名無しさん [sage] 2024/07/30(火) 23:13:56.95 ID:EnloT7kO >>979 >>値をムーブしちゃうのでstruct内部を参照したポインタが変なところを参照してバグる Rustでそのような自己参照はムーブでライフタイム切れとなるためバグは発生しなくて 自己参照を保ちたいならば値がムーブしなければよくて 値がムーブしないためにはスタック上でそのまま使うかヒープ上に確保して使えばよくて それを保証するためにRustではPinという枠組みがあって安全に取り扱えるようになってるよ http://mevius.5ch.net/test/read.cgi/tech/1716759686/994
995: デフォルトの名無しさん [] 2024/07/30(火) 23:19:18.00 ID:MqLM+D1V >>994 bindgenの作者に言ってあげればいいと思うよ ついでに改善したコードをPRしてコントリビュートしてみてはどうだろう 使用者のミスを擦るよりもずっと有意義なはず http://mevius.5ch.net/test/read.cgi/tech/1716759686/995
996: デフォルトの名無しさん [] 2024/07/30(火) 23:48:00.88 ID:dZ3/RfBM 同意 http://mevius.5ch.net/test/read.cgi/tech/1716759686/996
997: デフォルトの名無しさん [] 2024/07/31(水) 11:32:49.64 ID:yHR2oE13 結合が密過ぎないかこの言語 http://mevius.5ch.net/test/read.cgi/tech/1716759686/997
998: デフォルトの名無しさん [] 2024/07/31(水) 11:35:31.65 ID:yHR2oE13 >将来的に全部Rustで書けば起きないような問題 さっさと仕事しろおまいらってことですね判ります http://mevius.5ch.net/test/read.cgi/tech/1716759686/998
999: デフォルトの名無しさん [] 2024/07/31(水) 12:10:03.24 ID:yHR2oE13 >>985 Pin http://mevius.5ch.net/test/read.cgi/tech/1716759686/999
1000: デフォルトの名無しさん [] 2024/07/31(水) 12:10:59.00 ID:yHR2oE13 Pin<Arc<T>> http://mevius.5ch.net/test/read.cgi/tech/1716759686/1000
1001: 1001 [] ID:Thread このスレッドは1000を超えました。 新しいスレッドを立ててください。 life time: 65日 5時間 29分 33秒 http://mevius.5ch.net/test/read.cgi/tech/1716759686/1001
1002: 1002 [] ID:Thread 5ちゃんねるの運営はUPLIFT会員の皆さまに支えられています。 運営にご協力お願いいたします。 ─────────────────── 《UPLIFT会員の主な特典》 ★ 5ちゃんねる専用ブラウザからの広告除去 ★ 5ちゃんねるの過去ログを取得 ★ 書き込み規制の緩和 ─────────────────── 会員登録には個人情報は一切必要ありません。 4 USD/mon. から匿名でご購入いただけます。 ▼ UPLIFT会員登録はこちら ▼ https://uplift.5ch.net/ ▼ UPLIFTログインはこちら ▼ https://uplift.5ch.net/login http://mevius.5ch.net/test/read.cgi/tech/1716759686/1002
メモ帳
(0/65535文字)
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.026s