プログラミング言語 Rust 4【ワッチョイ】
Mozilla発のプログラミング言語「Rust」のスレです ■公式 https://www.rust-lang.org/ https://blog.rust-lang.org/ https://github.com/rust-lang/rust ■ワッチョイ スレ建て時、一行目に !extend:on:vvvvv:1000:512 を入れること ■派生元スレ プログラミング言語 Rust 4 https://mevius.5ch.net/test/read.cgi/tech/1507970294/ VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured 皆知ってるかもしれないけど、https://github.com/rust-unofficial/too-many-lists は良いね 公式のbookには無かった「自分で書いてみた時にハマる箇所と解決法」が丁寧に書いてあるんで、 特にプログラミング経験者でRust初学者には自信を持ってお勧めできる >>3 しらんかた webのやつはみれなくなってるね 製本?したものを上げてるサーバーが結構長いこと落ちてるね 1. cargo install mdbookでmdbookをインストール 2. git cloneで>>3 のリポジトリを取ってくる 3. 取ってきたディレクトリでmdbookを実行 4. book/ にhtmlで製本されたものが出力される ので、是非読んで欲しい。may not live longとかcannot moveとかで怒られまくってる人なら共感しながら読めるはず アンチスレのほうが伸びてるやん 枯れ木も山の賑わい 教えてください VecのDisplay::fmtをカスタマイズしたくて type MyType<T> = (Vec<T>); impl std::fmt::Display for MyType { } 申し訳ありません 途中送信してしまいました コードをplaygroundに移しました https://play.rust-lang.org/?gist=10bd65d0bfaf8b5117399b18bd8eb0d2 VecのDisplay::fmtをカスタマイズしたくて上の様にMyTypeを作成したのですが Vecのメソッド委譲するためのコードを手書きする作業が煩雑になって困っています 何か上手い回避策は無いでしょうか? >>9 私も初心者で分からないですが最終的に何がしたいんでしょうか? >>10 レスどうもです Vec(他標準 struct)のDisplay::fmt出力をカスタマイズしたいんです 例えば ・要素数が多い場合、最初の数個を出力して残りを省略するとか ・要素の出力が長くなる場合、適当なところで改行するとか ・インデントを受け付けてネストしてる場合は改行とインデントで整形するとか その上でVecのインターフェースをそのまま使いたいんですが >>9 のように新規の構造体を作る場合 手書きで委譲せねばならず どうにか上手く出来ないもんかな……と >>11 その用途ならVecに別な名前のメソッドを直接implしちゃってそっち呼び出せばいいような気がしたんですが println!("{}", v.my_fmt()); みたいに >>12 ごもっともです self.0に委譲するマクロが上手く書けなかった経験があり それに引きずられて本質を見失ってました コードを整理していったらいけそうな感じになりました https://play.rust-lang.org/?gist=960819f1fb1b5f9988a1c58cab2b1b9e& ;version=stable ありがとうございます >>13 ああ、なるほど Derefは思い至ってませんでした メソッド委譲の解決になりそうで助かります こちらもありがとうございます >>16 の論旨は「MyType<T>は常にVec<T>として扱われても問題ないか?あるならDerefはおすすめしない」だと思うけど、 今回の場合はむしろMyType<T>は特別なことが無い限りVec<T>として使いたいんじゃないの? >>16 読みました 見覚えのあるピンク玉はrust playgroundの中の人でした 「smart_ptrぐらいの同一性がある場合にはDerefが必要だけど strにDeref<Taget = [u8]>が無いように Derefだとやりすぎな場合もあるからdelegate構文欲しいよね」 ってなとこでしょうか strの例は「替わりにas_bytesがあるよ」ということかなと strとsliceとか他のライブラリを眺めた個人的な結論としては has_aならAsRef、is_aならBorrowをimplして受ける関数で使い易くしておくのが Rust的な落とし所なのかなーといった印象です AsRef, Borrow, Derefの使い分けは宣言的にプログラマの裁量に任されてる感じ よくよく考えれば自分のコードにもas_xxx, as_xxx_mutが散見されている現状なので Mytypeにもas_vecを書けばそれでも良かったような気がします >>17 自分のケースの場合はそもそもMyTypeがいらなくなってしまったもので Derefはオーバーパワーかなと思ってます とはいえ smart_ptrのように扱うならDerefが有用ということが 知見として学べたので 大変ありがたかったです >>17 このスレを読んでる人に情報共有してるだけだよ オライリー届いた。 分厚すぎてわろたわ。読むの大変そう。 dyn Traitが入ってしばらくしたらBox<Trait>はdisconになるの? deprecated扱いになって警告を出し次のepochで削除とかだったと思う impl Trait入ったらそもそもほとんど使わなくなるから気にしなくていいのか。 使うケース減るのもそうだけどepochで機能削除する場合はソースコードの変換ツールが提供されるらしい あと古いepochのソースはそのままコンパイルできるらしいから特に対応不要らしい だから新しいepochにしか入っていない機能を使いたいcrateとかでなければ何もしなくても困らないはずだし その場合でも変換ツール通せば簡単に対応できるはず epoch releaseってのはどういうことなんだってばよ? map: BTreeMap<K,V>で、keyが無かったら挿入、あったら格納されてる値vに応じて新しい値new_vに更新するか決めるってやりたいんだけど、 let v = map.entry(key).or_insert(new_v); if ... { *v = new_v; } よりもっと綺麗な書き方ある? https://webassembly.studio/ CやRustでWebAssemblyできるOnlineIDEだそうな Rust Never Sleeps: Community Grows, Eclipse-Based IDE Planned https://adtmag.com/articles/2018/02/01/rust-grows.aspx wasmってまだプリミティブすぎて使い物にならないのかと思ってたけど wasm-bindgen すげえな もうここまでできるのか Rustすごい! takahito takabayashiさんのツイート: "ファミコンのエミュレータをRust / WebAssembly で書き直した https://twitter.com/tatakaba/status/961532612723511296 苦労して書き直しても全然パフォーマンス上がらないのな… ぐうの音もでないほど効果があるユースケースってなんなんだ アルゴリズムが変わらないならそう変わらんのじゃないか 他人のひどいコードならともかく、同じ人が小規模なプログラムを書き直す程度だと特に C/C++からRustへ書き直して速度が上がったって話はあんま聞いたことが無い 速いネイティブライブラリを言語に組み込んでるJuliaとかなら、書き直すだけで速度上がったって話はちらほら pythonだったらnumpy使った方が楽でいいとかも いやだってjavascriptだぜ?アルゴリズムの問題か? c++もそうだがコンパイラに機能を詰め込むってのがそもそも筋が悪い >>48 やっぱりちょっと分からないな。 RustやC++のどの辺がコンパイラに機能を詰め込んでると思うの? ライブラリorツールに任せるってのもどの辺を任せたいのかな? 話がザックリし過ぎて言いたいことがよく分からないんだが。 プリプロセッサマクロのことかな?あとは型システムとかGCのことかな?ライブラリに任せるの意味がよくわからんが… C++はコンパイラの方もだけど標準ライブラリでの機能実現も相応に多くて結果ソースの記述が煩雑になっているのは既知の事実でしょう ライブラリや実装に任せた結果APIの統一が取れなくなって結局細かな仕様策定を余儀なくされたSchemeを見ても銀の弾丸でない事は明らかだよね それに出来る事を増やすという点においてライブラリは有用だけど変数の不変性や型システムのような制限をする事に関してはコンパイラによしなにしてもらうより他ないよ ☆ 日本の、改憲を行いましょう。現在、衆議員と参議院の 両院で、改憲議員が3分の2を超えております。 『憲法改正国民投票法』、でググってみてください。国会の発議は すでに可能です。平和は勝ち取るものです。お願い致します。☆☆ やっとstableでrustfmtできるようになったな >>45 は言語仕様の追加、更新が気に入らないんじゃないかな try!の代わりに?なんて以ての外だ、みたいな?それ以外に思い付かなかったけど 1.0以前に@や~を削除してライブラリにぶん投げた辺りは希望通りな気がする 基本的に電池入りじゃないRustはライブラリやマクロの代わりの言語仕様の追加じゃなく より効率的なバイナリを吐くための言語仕様の追加が多いイメージだけどなぁ、impl Traitとか >>56 あー、そういうこと。?記法は確かに若干違和感あったかもな。 でも実際、あれは便利なんだよなぁ。 File::open(path)?.read_to_string(&mut buf)?みたいに繋げられるから。 try!(try!(File::open(path)).read_to_string(&mut buf))は読みづらい。 かといって、 let mut file = try!(File::open(path)); try!(file.read_to_string(&mut buf)) みたいに2行に分けるのも面倒だし、無駄なローカル変数も出来れば避けたい。 結局、あれが妥当な判断だったと思うけど。 まぁ、stableにする必要あったのか?ってところで賛否両論あるかもね。 box キーワードは何時 stable になるんだ? boxキーワードはどういう時にうれしいのかがわからん 明らかに二行に分けた方が読みやすいわけだが。 新しい機能マンセー厨ってそういう感覚の狂いについて無自覚過ぎんだよね。 俺も違和感はあるけど、多くの人が賛意を出して採用されたんだから >>60 や俺の感覚が狂ってるんじゃね?自身の感覚の狂いって当然ながら無自覚過ぎんよ boxは在り様の総意を取るの面倒だし、目下はBoxで運用できてるしで、いつまでもstableに来なさそう ヒープを多用したい人には文法にあればありがたいんだろうけど、そもそもヒープが好まれんしのう boxっていきなりヒープにメモリ確保されるのが保証されたりするんじゃないの? 今はコンパイラ次第じゃん ironって今メンテされてないのか 最近のweb FWはrocketの方が人気なんかな nightly専用だからまだ手を付けてないんだけど それはInPlaceとかPlacerがあればよくてbox inはただのsyntax sugarでは 分解の方がよほどsyntax sugarじゃないのかいな NightlyのInPlace, Placer使わなくても、Stableの環境でmacro使って実現出来そう boxって名前はBox<T>以外に使う場面で綺麗に見えない place <- exprは代入みたい tokio-coreなくなるんか 一通り組み上がった後の悲しいニュース まじか、ちょっと辛いな 依存してるライブラリも結構あるよね tokio系列のやつってtokioとかtokio-coreとかtokio-ioとかtokio-protoとか複数あってよく分からんのよね tokio-ioのリポジトリにはtokioに移動したからもう使うなって書いてあるし tokio-coreは移動じゃなくて廃止予定って書いてある… tokio-protoはそのまま?tokio-timerとかtokio-serviceとかよく知らんリポジトリもあるし… 誰か各クレートの特徴(役割)と関係性を教えてくれ >>71 あっちは、アンチが立てたキチガイ専用スレだからいいんだよ コミットを追うとtokio-coreはtokioに変わったように見える tokio-core=tokioでtokioの本体 tokio-ioはtokio-coreを使って非同期ioを実装したものだったがしゃらくせえのでtokio-coreに取り込んだのかな tokio-protoはtokio-coreを使ってネットワークプロトコルを実装したものだったがしゃらくせえからtokio-coreに取り込んだのかな つまり tokio = tokio-core + tokio-io + tokio-proto か? [] [[[ [[ [] ][ [] [ ] [] ][]] [[[ [] } tokio-protoとtokio-serviceってtrait宣言が主体のインターフェース定義クレートだったような? 前者はクライアント、後者はサーバに適したインターフェースが定義されてた覚えがある io, timer, cpupoolなんかはユーティリティ機能が実装されてたよな 統合の基準はどこかで議論されたんだろうけど、どこでやってたのかな 【お知らせ】Packt出版より Network Programming with Rust が発売されました。 https://play.rust-lang.org/?gist=cb511b34bc3ffbb43b8589a24156337a& ;version=stable let mut foo = Foo{ a:0, b:0, c:0 }; let aaa = ["5", "432", "3"].iter().flat_map(|i| i.parse::<u32>()).collect::<Vec<_>>(); foo.a = aaa[0]; foo.b = aaa[1]; foo.c = aaa[2]; Rustってこれ以外に書き方ありませんか? tupleでやってみるとleft-hand of expression not validと出ました >>79 大量のフィールドに値を入れるのって 一行一行書くしかありませんか? 一行にしたいなら foo = Foo { a: aaa[0], b: aaa[1], c: aaa[2] }; でも良いだろ。 部分書換なら foo = Foo { a: aaa[0], .. foo }; とかもある。 朗報: ついにウェブプラットフォームでRustが速度性能トップを取る https://www.techempower.com/benchmarks/#section=data-r15& ;hw=ph&test=plaintext なお、JSON操作を伴うとJavaにも劣る模様 ツリー制御が不得意すぎて笑うわ JSON serializationはそんなに悪くないんじゃね?tokio-minihttpで96.2%出てる。 それよりSingle QueryとMultple Queryが遅いのが問題じゃね? serdeでシリアライズだけするぶんにはjavaの1.4倍くらい早かったんだけどなあ(俺調べ) Rust book first editionからの変更知りたいんだけどバージョン差分どこでまとめられてる? >>83 >>89 なんで自分で調べようともしないの? Rust Languageさんのツイート: "Announcing Rust 1.24.1: we had some regressions in 1.24.0, so we've released a patch release. Please check it out! https://t.co/zrItc0qiqD" ; https://twitter.com/rustlang/status/969367994072739841 👀 Rock54: Caution(BBR-MD5:b73a9cd27f0065c395082e3925dacf01) Iterator::mapに渡すクロージャ内で、クロージャ内の変数への参照を持つstructを返したい時ってどう対処するのが正解ですか? https://play.rust-lang.org/?gist=a15e0dfa10339570fef5b9225761a9f0& ;version=stable does not live longエラー関係は自分が思ってるより広い視点で見た方が解決するんじゃないかなあ Hito.konomi_no_mochiは参照なんだから、参照元としてVec<Mochi<'a>>を保持しないと駄目なんじゃね? =>mochiがMapになってて分かりにくい =>とりあえずcollectさせてVec<Mochi>持ったら動いた みたいな。 https://play.rust-lang.org/?gist=6c9947e3584f1feb5bb14f07d27aa9c7& ;version=stable 多分、頭の良い人ならもっと綺麗な説明と解法があるんだろうけど >>92 ありがとうございます 仮引数mのライフタイムはmain関数が抜けるまでだから通るということで合っていますか またVecではなくIterator::Mapだと駄目な理由は、Iterator::Mapはcollectされるまでクロージャが実行されないから…とかでしょうか >>93 仮引数mのライフタイムはクロージャ内なのは変わらないよ。>>92 は仮引数を参照じゃなく消費してるから通る(>>92 の&mじゃなくてmで良い) クロージャが実行されないから、ではなく、mochiの値が消費されてるのにその参照を持たせようとしてるから駄目 試しに>>91 のコードでmochi.map(|m| { 0 })とか書いて、mochiをprintln!に渡してみようとすると怒られるよ。もう使ってるって。 そこらへんの細かいルールを覚えるの大変だし、コンパイラもまだ分かりやすいエラーメッセージ吐いてくれないから、 ・参照を使うときは、参照元をちゃんと生かしておくこと ・参照を使った構造体は、元の値を修飾(見方を変える、新しい機能を持たせる等)するようなパターンに限定すること を守るようにした方がいいよ >>94 「消費したものの参照を持たせるのは駄目」と「消費しているから通る」はそれぞれはわかる気がするのですが、両方となると… 前者の「消費したもの」と後者(main関数中生き続けるMochiのベクトル)は別物だと思うのですが、 前者で駄目な理由は関数中生き続けるMochiがない(mapを呼び出しただけでは駄目)ということですか? 「消費されるので通る」じゃ言葉足らずでした。「参照じゃなくmoveして延命している」の方が通じるかも >>91 のコードを整理すると 1. HitoはMochiの参照を持ってるから、Hitoが有効なスコープ中はMochiも有効じゃないといけない 2. mochiはinto_iterで作られてるからMochi型を吐き出す、けど所有はしない 3. なのにmochizukiはmochi.map()で各要素への参照しか持たない 4. mochiから吐き出されたMochiの受け皿が無いんでエラーになる これを解決するには 1を変えてHitoがMochiを所有するようにデータ構造を変える 2で作られたMochi型の値をしっかり保持する変数を用意する の2種類くらいしか思いつかん。 Does Not Live Longエラーはライフタイムがどうのこうのと小手先で弄るより、 値の所有者を明快にしたり、データ構造を見直してみると案外素直に直せるのが経験則。 >>96 loop{ let (a, cond): (&str, bool) = get_too_many_str(); let m = Mochi{aji: a}; let h = Hito {m : &m}; if(cond){ break; } } // ここでhのvecが欲しい この場合は、ムーブする(ループより長いライフライムの)変数がないので1の手法しかないということになりますか? そこそこでかい文字列を扱っているので気を使っていたのですが、この場合Stringにすべきでしょうか 大きい文字列を扱うから参照にしたいってのは普通にあるし分かるけど Hitoが&MochiでなくMochiをメンバに持つようになっても文字列のコピーは行われないよ 自分なら>>97 のget_too_many_str()が返す&strの元を誰が保持するのかをまず気にする そこをしっかり把握してれば文字列のコピーは最低限になるはずだから >>97 んー、自分なら そこだけに使うMochiCow型作ってでも ajiの型をCowにして凌ぐかな &strの元もloop内の変数が持っています hのvecを作るにはコピーは避けられないようですね… &strからStringに変えたところhvec.push(h)してもエラーにはなりませんでしたが、 スコープを抜けたはずの変数が使える理由ってどこかに書いていますか? そりゃloop内の変数hから、loop外のhvecに所有権が移動したから 頭の中に入れておける物なんて極わずかだし、場当たり的にdoes not live longエラーに対処するのは大変なので、 ・値の所有者はどの変数であるべきか ・データ構造はどうあるべきか という観点だけ念頭にいれて、「性能を稼ぐために参照を使おう」って考えを一旦外すとスッキリするよ まともな話題はslackいっちゃうのかな。 匿名で喋りたいのはアンチ向きか 別にアンチって訳じゃないけど、コンパイルが遅すぎる(特に最適化掛けた場合に)のはどうかと思う。 実行が速くてもその生成に時間が掛かれば無意味でしょう……。 >>108 Rustで組んだ新Firefoxの動作が2倍ほど速くなったのは無意味? まあコンパイルは遅いわな。 ていうかcargoの仕組みが問題なだけか? rustcで単一ファイルだけコンパイルすると結構速いなと思った cargoって警告無視のオプション(-Awarning)の有無でも一からビルドしようとしたりちょくちょくお粗末 なんかRustってテスト用と製品用で別々の最適化を施せるんじゃなかったっけ。 俺は自分の為だけにRustを使ってるのであまり気にしたことがないが。 確実にどんな人でも可能なネットで稼げる情報とか 念のためにのせておきます グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』 C717P rustを始めたんだけど 分かりそうで分からなくて イライラする なんだこの言語 他の言語の経験にもよるけど 3000行ほど書けば慣れるよ(適当 actix_webでちょちょいとwebサービス作ろうと思っただけなんだが externとuseみたいに、なんで同じようなものが2つ有るのとか trait?、インプリすればいいだけならなんでこんな名前なんだとか 察するにJava経験者かね externは外部ライブラリのモジュールを参照する宣言 modは自身のフォルダ以下のモジュールを参照する宣言 useはモジュールの要素(Struct or Trait)を取り込む宣言 pub use self::MyStruct; // 要素をexportしたり use std::io::Error as IOError; // as で別名つけたり use super::Result; // 上位の型を取り込んだり(mod.rs以外からだと同一フォルダのmod.rsを見にいくので注意) 肝はselfとsuperを使いこなすことかと このあたりリファレンスに書いてあるんで落ち着いて読んでもらえばいいけど インプリについては、Trait = Interface(Java)の理解でそれほど差し支えない気もするけど (定数は同じ階層のmoduleに移す) AssosiatedTypeがあるように"Traitはコンパイル時に解決できる"ものってのを 意識してればその内に腑に落ちるんじゃないかな ただこんなこと言うと 「RustのTraitは厳密なtraitじゃない論争」(Wikipedia参照)が始まっちゃうかもしれないので ゆるく受け流してほしいところ extern/use周りをrefineする話ってどうなった? チュートリアルの和訳のところを読んでいるけど 誰が訳したんだろう。。。 extern crateは、includeとかload libraryぐらいの意味だと思えばいいと思うが、 「え、それ、Cargo.tomlにもう書いたやん」って思うのは当然の感覚だな しばらくしたら言語仕様変わりそうだなあこれ 勉強していくべきなのかどうか迷う 仕様の改定はc++のようにコンパイラのリリースとは別に2〜3年毎に定めることになってる 将来のコンパイラでも古い仕様を選択して使えるはず どんな言語でも利用者多ければライブラリーのトレンド変わっていって学び直しはあるし 言語仕様の変更だけ特別視する理由が分からん ver1.0になったし、firefoxに200kstepのソースがあるから始めるなら今でしょ ruby1.8から1.9とか python2から3の変更とか 嫌じゃん 言語もライブラリも混在してぐちゃぐちゃ >>124 和訳は最新に追いついていないと思います、公式英文を確認したほうがいい Rustの場合仕様変更の影響を受ける記述はコンパイラがwarning(とsuggestion)出してくれるみたいだし むしろライブラリのアップデートより楽なんじゃないかな やりたいことをするのに1日使って50%しかできなかった 自分には無理だこの言語 ここにまともなRustユーザいないのは年寄りしかいないからなのかなぁ slackかtwitterでコミュニケーションとれるので5chへ書き込みたい事情があまりない >>138 おすすめのハッシュタグはなんでしょうか? もっとメジャーになってslackが荒れて来たらここもワンちゃん slackで発言できないアンチにしか存在価値がないのかぁ つまり変な人でもスレに繰るなら、山の賑わい人気の証ってことね Vec内のアイテムを複数条件やand or等をユーザに指定させてフィルタリングをしたいのですが 無理にでもSQL使うべきでしょうか ユーザってのはどういうレイヤの話をしてるの?もう少し具体的に書かないと意味不明 values.iter().filter(hoge).filter(fuga).filter(piyo) フィルターを何度がけすると型がやばそう 調べてみるとfiltersというクレートがありました いやじゃ、いやじゃ、Eclipseなんぞ使いとうない みんなどんな環境で書いてるの?今はvscode使ってるんだけどrlsがあまりに不安定すぎてストレスが… emacs + flycheck racerは重すぎるんでOFFにしてる 日本語の発音ってかイントネーションはみんなどっち? ラスト(ミファファ=スタバ) ラスト(ミドド=ベスト(着る方)) Rustの型って何を言ってるのか良う分からないくらい一気に複雑になるんだけど、改善の兆しってある? filter(|x| ...).map.(|x| ...)ってやると戻り値がMap<Filter<...>>みたいに、情報量がほぼ増えないのに型の表記だけが増えてくのが見づらくてしゃあないんだが 「ここを関数に切り出しておきたい」ってのも難しくね? impl Traitあるだろって言われるけど、自分ひとりでできた試しが無い >>173 .filter(|x| ...).map.(|x| …)とやったら ざっくり言うと戻り値はIterator<Item=T>でowned, shared reference, mutable referenceの3種類 Map<Filter<...>>とかの詳細な型を知りたいと思うことは基本ないからそこまで困らない デコレータとかコンポジション的なものとして理解しとけばいいと思う 関数に切り出すのはGC言語と比べると難しい どの値の所有権をどの呼び出しレイヤーで保持すべきかを整理しながらリファクタリングする必要がある ただある程度パターンがあるからそれが理解できるとそこまで難しくはない >>174 標準ライブラリでiteratorのメソッドならそうなんだろうな、って他言語でも溜め込んだ知識で何とかなるけどさ、 例えばwarpっていうWebフレームワークはリクエストの解決にfilterを使ってるんだけど、 https://docs.rs/warp/latest/warp/filters/index.html ↑ここからたどって、例えばリクエストのパスにマッチするフィルタを作成するwarp::filters::pathってのがあるんだけど、 こいつの戻り値が独自型のExactってやつなのね warp作ってる人はここに様々な条件を追加できるようにしているんだけど、pathの戻り値にどう組み合わせられるかってのをどう探せるんだろっていつもなってる 他のcrateも、単機能で目的果たせるライブラリならまだいいけど、高階関数で機能組み合わせてねってやつはrustdoc見ても意味が分からなくなってる >>175 ExactがFilterだと分かれば別のFilterを組み合わせられることはわかるでしょ? warpのFilterシステムを理解させるための解説ドキュメントが不足してるのと 他で類似の仕組みをあまり経験したことがないのが理由なんじゃないのかな? 型が入れ子の形でチェインされてる状態に慣れてないから それがわかりにくさの原因のように感じるかもしれないけど JavaやgoのReader/Writerみたいにデコレータ的に型を重ねていくのはそんな特殊なことじゃないよ iterator系の処理はどんな言語でもやりすぎると意味不明なんでいい単位で説明変数や関数に切り出すのは大事だよ。 関数単位で切り出す場合はimpl TraitやBox<dyn Trait>使った方が良いと思う 実装の詳細が型として露出してしまうのはよろしくないし 何より長い型を書き下すのはめんどくさい >>176 いやExactがFilterかどうかが分からないんだ。自信が無い https://docs.rs/warp/latest/warp/filters/path/struct.Exact.html https://docs.rs/warp/latest/warp/trait.Filter.html ↑2つを見ても、ExactがFilterをimplしているとは書いてないんだ 知ってたらマジで教えてほしいんだが、どこ見ればいいの? >>178 そう思うのは人情だが、じゃあどういう型の関数にすればいいのかって話 ググらずに分かる?俺は分からなかった >>179 非公開の(だけど実装が漏れている)FilterBaseトレイトを介してFilterを実装してるんだね…… FilterBaseが公開されていればExactのblanket implementationsに出てくるはず 同じことは指摘されているが放置されている模様 https://github.com/seanmonstar/warp/issues/742 もしかして特段に分かりづらい構造だったのかWarp Sealed TraitっていうユーザーにTraitを実装させないための一般的なパターンなんだけど privateなTraitはドキュメントには現れないのでExactがFilterBaseを実装してることを確かめたければソースを見るしかない でも関数や構造体の説明にFilterだよって書いてるんだからまずはそこからじゃないか? path()「Create an exact match path segment Filter.」 Exact「A Filter matching an exact path segment.」 いや型の説明がコメントにしか無いかったら疑うのが基本じゃないか…? 説明にある通りの使い方はできるけど、何故そう使えるのか分からない、となった上での話 前にもちらっと書いたところもそうなんだけど、impl Filterを返す関数のシグネチャも独力だと分からなかったんだよ。もっと情報の少ないクレートでやる必要が出てきたら詰んじゃう [T]と[T; N]があるように strに対するSizedなstr<N>とかできんかね ttps://doc.rust-lang.org/beta/unstable-book/language-features/yeet-expr.html 名前の元ネタがよくわからん >>185 trY Early-ExiT で yeet じゃない? experimental だからわざとクソ命名してそう。 ProviderとDemandってCOMのQueryInterface的な使い方もできるのかな cargoのsparse protocolは嬉しい Default alloc error handlerはLinus指摘の取り込みかな。 Linusの話は、メモリアロケーション失敗時にpanicするなという話だと思うけど、今回の変更とは全く関係ない 今回の変更でalloc crateがalloc_error_handlerのデフォルト実装を提供するようになった 新たに提供されたalloc_error_handlerはpanicする実装になっているので、メモリアロケーション失敗時にpanicになることは変わらない 単に、利用者がalloc_error_handlerを独自に実装する必要がなくなったというだけ Linusの指摘に対しては、Box::try_newなどのアロケーション失敗を呼び出し元に通知するAPIを用意することで対応している >>195 サンクス。 Linusは「単にエラーを返せ」と言っていたから、error handlerじゃ確かに駄目だね。 Rust製の高速なwebpack互換バンドラ「Rspack」登場。現時点で5倍から10倍の性能向上 https://www.publickey1.jp/blog/23/rustwebpackrspack510.html > Rust製の高速なバンドラとしては、webpackの主要な開発者がNext.jsに入社してwebpackの後継として開発している「Turbopack」もあります。 > 現時点ではまだwebpackが抜きん出た人気を得ていますが、現時点で主要な開発者が抜けてしまったwebpack後継の座を狙った競争が始まったといえそうです。 >>197 ちょっとスレチ気味だけれど Turbopack(新調で700倍高速) vs Rspack(互換性維持で5~10倍高速) webpackからの乗り換えはしばらく様子見 一度普及したソフトの作者自身が後継プロジェクトを立ち上げてもなぜかうまくいかない法則 速度遅くてもウケたプロダクトの動作速度上げたところで 現行をリプレイスする理由にならないからな それにRustがいかに速かろうと今の時代ネックはIOである可能性が高いし >>200 詳しく見ていないけど、ロジックにボトルネックがあるのかもね。 10倍のオーダーで速度差出るなら性能がリプレース理由になる場合も増えると思うよ 数分かかる処理が数秒で終わると快適さが全然違うだろうし >>201 どうせ IO がネックだからってのは昔から言われてることだけど クラウドサービスを前提にすると事情が違うと聞いたことがある。 レスポンスタイムにあまり差が無かったとしても課金は演算量 (CPU の使用量) に対して だからなるべく効率的に実行できる言語を使ったほうが安く上がるんだとさ。 Ruby on Rails 6 では、webpack が標準だったけど、 Rails 7 では、Import Maps で、CDN から直接インポートするように変わった。 脱webpack/node.js ES2015 に対応していないブラウザ用に、バンドルする方法もある。 バンドラーは、esbuild, rollup, webpackの3つ ドキュメントコメントを reStructuredText で書きたい let-else の else ブロックの中だけ rustfmt 効かなくて設定間違えたかと思ったら フツーに未対応だった https://github.com/rust-lang/rustfmt/issues/4914 let-elseは鬼っ子だから 改行位置決めるのも大変 横から済みませんがが、 Rust で Vec に要素を追加した場合にメモリー不足になったかどうかを検出 するのはどうしたらよいんでしたっけ? >>210 それは予め領域を確保しておく関数で、確保できなかった場合には、 Result<(), TryReserveError> という戻り値を返す関数と言うことですか? そして、関数呼び出しの直後に ? を書くと、エラー発生時にそこで アプリをダウンさせると言うことですか? >>211 事故レスですが、? 演算子は、x ? と書くと、x の値が Err(y) だったら、 return Err(From::from(y)), というような動作をする関数のようですね。 いろいろ違う 落としたいならpanicさせとけばいい メモリ不足を検出した場合に何をしたいかで適切な対応は変わってくるけど、何をしたいの? >>214 メモリー不足の時にメモリー不足である旨のエラーメッセージを出して、 なんらかの自作の処理コードを動かしたいです。 >>215 なお、Vecに追加する動作を行なった関数の中で処理をしたいです。 重要: メモリ不足だからと言ってmallocが失敗するとは限らない 今の Linux カーネルだとアプリケーションからオーバーコミットを無効にすることは出来るようになってるぞ。 try_reserveの戻り値がErrだったら処理を実行するだけだよ この説明で分からないならenumやResult型について勉強した方が良いよ あとtry_reserveの失敗要因はメモリ不足だけじゃないけど、エラー種別はnightlyじゃないと取得できないみたいね RefMut <-> Ref にも Rc <-> Weak みたいな相互変換メソッドがあればいいのに >>220 RefCell自体を取り回して必要なところで都度RefやRefMutを作れば良いのでは >>221 実際今はそれでやってて、別に問題になるほどじゃないんが、ちょっと無駄だよなあと Ref/RefMutってあんまりあちこち取り回す用にできてないよね >>222 RefやRefMutはMutexのGuardみたいなもんなんだから取り回す範囲は極力狭くするべきなんじゃね Rust for Linux updates! More pin-init and refactoring! - YouTube https://www.youtube.com/watch?v=jAanHvcuYtA The RustConf Keynote Fiasco, explained https://fasterthanli.me/articles/the-rustconf-keynote-fiasco-explained 一連の事件は結局不幸な伝言ゲームの結果だったということだろうか 以前からCodeLLDBでたまに値がちゃんと表示されないことがあるなーと思ってたら再帰型が原因だったんですね 今ほとんど再帰でできてる部分触ってるせいで困ってる…… dbg!書けばいいだけではあるんだけど泥臭くて嫌だわね https://github.com/vadimcn/codelldb/issues/605 いつのまにかrust-specがマージされてる。まだ作業終わってないけど。 ttps://github.com/rust-lang/rfcs/pull/3355 ttps://github.com/rust-lang/rust/issues/113527 rustにもようやく仕様が。 これから編集者雇うみたいだからまだまだ時間は掛かりそうだけど、前進だね Hugging FaceがPyTorch的なRust製フレームワークを作り始めたらしい https://github.com/huggingface/candle githubにrustupのソースコードあるから読めばいいよ。 Debugを上位トレイトに持たないトレイトのオブジェクトをなんとかしてdbg!する方法は無いもんじゃろか 構造体フィールドの中身を知りたいという事ならAnyを継承させてダウンキャストするかDebugを継承したtraitにするしかないね intellij rustからRustRoverギリギリ燃えてないな。プラグインもIDEAもバグが増えたのが懸念とか言われてるけど。 RustのコンパイルターゲットはTierで分けられているけど x86_64-pc-windows-msvc ←Tier1 x86_64-unknown-none ←Tier2 この違いって何? Tier1の条件を見るとすべてのテストに合格すること的な事が書いてあるしプラットフォームが不明の状態でそれは不可能はなず 組み込み向けなどの低レイヤー用途を想定したターゲットにTier1のものはなくすべてTier2以下になっている もしこれが理由なら自分が書いたコードはTier1と同レベルに翻訳される(実行できなかったり実行結果が不正なコードは生成されない)事が 期待できるけどそう考えて問題ないのだろうか >>241 x86_64なら現実的にはほぼ動くとは思う ただ、あくまでもrust側ではコンパイルが通ることしか確認してなくて、生成されたコードが正しく動作するかは未確認の状態 利用者側が動作確認をきちんとやる必要があるよ >>242 例えばベアメタル開発用などでOSとインターフェイスしないコードのみほしい場合 x86_64-pc-windows-msvc(x86_64-unknown-linux-gnuとかでも可)でスタティックリンクのライブラリとしてビルドしてカスタムリンク x86_64-unknown-noneでビルド の二択だと出力物の信頼性はどちらの方が高いのだろうか。どちらも適切なローダーを用意すれば動作するはず 特に低レイヤーの開発で翻訳不良があるとトラブルシュートが沼りやすいし、前者の方が有利なら ゴミが付いたりビルドが複雑化するなどのデメリットを考慮しても検討する価値があるはず より正確にはtier2はwith/without Host Toolsに分かれる。 withの方はtarget環境扱いだけじゃなくてネイティブなhost toolsを使用して開発環境として使える。 *-*-none-*はベアメタル向けだからHost Toolsのサポートはない。 言い換えるとtier2 with Host Toolsはセルフホストできる。 Tier 1にもwith/withoutの分類があるけど事実上withoutの方がない。 これは今のところHost Toolsをサポートしてないtier 1が存在しないから。 だからビルド環境に指定したいならx86_64-unknown-none。 x86_64-unknown-noneが吐くコードをどのくらい信用して良いのかって話ね Tier2=十分にテストされていない=不正命令例外を吐いたり意図しない演算結果になる可能性がある とかだと開発に重大な影響が出るし勘弁してほしい。Tier1のターゲットならそんな可能性は無視できるはずだし テスト云々はlibstdが主なんでは? そもそもコード生成するのはLLVMなんだし機械語レベルじゃRust側のTierは関係ない気がする x86_64-unknown-noneがTier2の理由がstdのテストができないからならそれでいいんだけどね Platform Supportを見ても >x86_64-unknown-none * Freestanding/bare-metal x86_64, softfloat としか書いていない。hardfloatが使えない?のはよくわからないが Tierはrustcのコードベースがビルドできるかどうかの保証であって吐くバイナリの質の保証じゃない。 そもそもrustcはフロントエンドだからどういうバイナリ吐くかは無関係。 tier 1/2の違いは自動テストが常に実行されるかどうかの違いだけ。 全部Platform Supportに書いてあるからこの説明でわからんならどこが理解できないのか言ってくれ。 Tier表記がアテにならないならコードの質を比較するにはどうしたらいいんだろ x86_64とavrが同じ品質、同じ最適化レベルなわけないよな rustに限らずコンパイラの生成コードの品質はアセンブリ見て判断するしかないんじゃね LLVM IRもプラットフォームごとに差があるのかね? Rust製ブラウザエンジンの「Servo」、アプリに組み込み可能なクロスプラットフォーム対応WebView化を目指す。Electron代替を目指す「Tauri」への組み込み実現へ - Publickey https://www.publickey1.jp/blog/23/rustservowebviewelectrontauri.html 期待 https://rust-lang.github.io/rfcs/3192-dyno.html 気づいたらポシャっててstd-1.73.0からProvider/Demandも消えてた やっぱりRTTIとかそういうのはあんまり乗り気じゃないのかな?? RubyのYJITって仕組みはRustで実装されてるんだな ソース見てビビった >>253 へぇ、Node.jsもあちこちが遅いからと ちょこちょこ便利ライブラリの中身がRustに置き換わり始めてるし 今後こういう流れは加速しそうだな 遅い部分を Rust でなおそうというよりは、 Rust へ置き換わる流れに乗るついでに駄目なところをそろそろなんとかしようぜという感じじゃないかな。 イマイチなのがわかっててもちゃんと動いてるなら何かきっかけがないと重い腰が上がらないのはよくあること。 YJITのコード、相当面白いな RustでJITしてるよw マシンコードゴリゴリ生成してる rustってJavaやpythonみたいに爆発的に流行るわけじゃなくてじわじわ広まっていく感じなんだろうな YJIT、最初はCで実装されてたがRustに変えたみたい bindgenでCRuby側のAPIをRust側に持ってきて それを使いながらJITでマシンコード生成してる 面白すぎる コードもめちゃくちゃ読みやすいぞ RustのRTOSはTockがあるけどFreeRTOSやTOPPERS/SSP、μT-Kernelなど既成のRTOSとの比較レビューってある? read.cgi ver 07.5.0 2024/04/24 Walang Kapalit ★ | Donguri System Team 5ちゃんねる