Rust part12
■ このスレッドは過去ログ倉庫に格納されています
crates.ioのライブラリを読んでて見つけたんですが、 traitを実装するのに、まず構造体に直接同名のメソッドをimplして、 traitの実装ではそれを呼び出すだけ、みたいな方式でやられていました Sがstruct、Tがtraitだとしてこんな感じです impl S { pub fn f(&self) {...} } impl T for S { pub fn f(&self) { self.f(); } } これってimpl T for Sのほうに直接実装するのに比べて何かメリットがあるんでしょうか? >>480 alert()って簡易テストくらいでしか使わないような >>481 意味が不明です >>482 例えば今適当に作った例だけど struct S { x: i32, y: i32, } impl S { fn fmt(&self) -> String { format!("({}, {})", self.x, self.y) } } impl std::fmt::Display for S { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "S{}", self.fmt()) } } fn main() { let s = S { x: 123, y: 456 }; println!("{}", s.fmt()); // (123, 456) println!("{}", s); // S(123, 456) } >>482 内部用の非公開関数は impl S { } の方にしか書けないから実装は全部そっちに書いて impl T for S { } からは呼び出すだけにした方がすっきりする場合がある >>483 これ見て思ったんだけど、 メソッド名と引数全く同じだった場合で、 構造体のメソッドがpubで、 トレイトのほう優先的に呼び出したい場合ってどうするの? そもそもメソッド名被らせるなって話ではあるんだけど すみません、impl Sもimpl T for Sもpubは付いていませんでした…… Tがpubなので、外部にはTの実装としてのfだけが見える状態ですね >>483 振る舞いを変えたいなら分ける意味も分かるんですけど、完全に同じなんですよね >>484 すっきりするというのは確かに読んでて思いました 実際非公開の関数が他にもありました 結局これが最大の理由なんですかね? >>485 こんな感じでいけますね https://play.rust-lang.org/?version=stable& ;mode=debug&edition=2018&gist=10cdbd17798b14faa5fb6619ceb0739d >>473 match お前の職場にはコーディング規約がないの? { 規約でunsafeが許されている => { ならunsafe使うの自由だろ。問題があるなら規約を改正しろ } 規約でunsafeは禁止されているが使ってるヤツがいる => { ならなんでunsafeを利用してコーディングしてるヤツがいるんだよ。そいつをなんとかしろ } } 結論 別に許可されてるなら自由だろ それが問題だと思うなら上司にいって禁止させるのが先 おっと最後にこれが必要か _ => { コーディング規約ぐらい決めとけ。決められてないぐらいの組織にいるなら文句いうな。諦めるか転職しろ } 規約で禁止されていてみんな守ってる場合にコーディング規約決めろと怒られるバグ >>491 規約で禁止されてるなら単純にそいつの問題だろ それがなんで競プロの影響になるのかまったくわからんぞ 動かないコーディング規約を作られても困るわ どのタイミングでもいいから自動で弾く仕組みまで作らないと …誰かgit hookの練習で作ってみない? こういうキチガイがいて邪魔だから 競プロは専用スレを立ててそこへ隔離すること rust書いたことない障がい者が騒いでるな ゴミコード晒して叩かれたのが相当悔しかったのか なら自分の腕を磨けよ やってることが数人しかいない過疎スレを荒らすって どうやったらそう言う思考になるわけ そら競プロの解答コードが規約破りまくりなの見れば関係はあるわな そもそもunsafeの利用の明確な基準って決められるのか? 利用を完全に禁止することはできるかもしないが、使ってOKな条件を担当者の最良が入り込む余地がないレベルで厳密に決めるのは難しそう >>498 例えばVecの実装にも一部unsafeが使われておりunsafeは忌避すべきものではなく有用なものであるがその使用には厳しい条件がある @unsafeが極狭い範囲に閉じ込められており抽象化されたインターフェースによりその存在を意識せずに使えること Aunsafeを使用することで明白にその操作の効率が良くなるもしくは低レベル操作によりその使用が避けられないこと Bunsafeの使用部分がその関係する範囲全体の一貫性において完全に安全な操作であると確認できること 以上3点が関係者により合意確認できている場合のみunsafeの使用が認められそして上位ではその存在を気にせず安全に使うことができる >>498 unsafeのコードにはレビュアーを最低5人指定すること とすればok 使わざるを得ないパターンを提示(この時点で滅多に無い事が分かる)、当てはまらない物は原則禁止 本来要らない箇所で使おうとする輩が湧いて出ないようにするのが目的 ノーコメントunsafeは問答無用で禁止くらいのことはしてもいいと思う そのくらいunsafeはやばい stdのunsafe APIに関してはそうだと思うけど crates.ioのライブラリ群にまでそういうの持ち出されると面倒だなあ clippyもpubなunsafe fnにはドキュメントコメントに # Safety のセクションがないとデフォルトで警告出すので コメントつけるのは最低限やっておくべきラインだと思う https://rust-lang.github.io/rust-clippy/master/#missing_safety_doc 競プロの人ってレギュレーション守れば何してもいいって考え方の人が多いよね。 規約次第ってのが正にそれ。 unsafe みたいに取り扱いが繊細な機能は基本使わない、使う時には議論した上で限定的に使うみたいな感じに取り扱うのがほとんどだろ。 規約で機械的には決められないと思うよ。 競プロでunsafeなんて使わないよ グローバル変数おじさんなら知らんけど 久々にusize祭りキタ━━━━(゚∀゚)━━━━!! unsafe fn calc(bit: i32) -> i32 { if bit == 0 { return 0; }; if DP[bit as usize] != -1 { return DP[bit as usize]; }; let mut start_id: i32 = 0; for i in 1..=K_NUM { if bit & 1 << i == 0 { start_id += C_NUM[i]; }; } let mut res: i32 = i32::MAX; for i in 1..=K_NUM as i32 { if bit & 1 << i > 0 { let mut end_id: i32 = start_id + C_NUM[i as usize]; let mut num: i32 = end_id - start_id - (SUM[end_id as usize][i as usize] - SUM[start_id as usize][i as usize]); res = res.min(calc(bit ^ 1 << i) + num); } } DP[bit as usize] = res; res } Rust競プロでグローバル変数(static mut)はマジでおすすめしないぞ、ほんまに 意味わからんWAの原因になりうる https://qiita.com/qnighy/items/46dbf8d2aff7c2531f4e >>509 それはRustだけでなくcやc++でも起こることなので、注意すれば大丈夫ヽ(´ー`)ノ Rustだから駄目、c++ならokという根拠にはならないから >>511 1%でもダメな箇所があったら全部ダメって考える人? 規約になんもないからってunsafeまみれだとぶっ叩かれるぞ そう、actix-webの作者のように >>507 添削しました。お収めくださいまし。 1. 安易にグローバル変数を使うな。状態を引数で持つくらいやれ 2. 引数bitが負になるのかくらい考えろ。脳死でi32とusizeをコピペしてるだろテメー 暗黙のキャストが無い==明示的にキャストすればいい、じゃねえぞ パッと見て汚いなら設計が汚えんだ。動的プログラミングだから汚えんじゃねえ、テメーが汚えんだ …負数になる可能性がある場所はたったの1行じゃねえか!どうした?頭使ってる? 4. unsafe外す努力もしねえのか、どうした?5回deleteキー押せば外れるぞ? 5. 値とインデックスが混ざるような書き方、どうして怖がらない?ロボトミー手術でも受けたのか? 6. C/C++には無い機能も使わず、warningもlinterも無視して、一体どうしてrustで書いてるんだ? 勉強中とすら言えねえじゃねえか。 まさか、VBAスクリプトを.javaファイルにコピペして「動きません!javaはクソ!」とか言っちゃう伝説のコーダーなのか? 質問です デフォルト値を与えるトレイトDefaultについて例えば #[derive(Default)] struct S { a: i32, b: i32, c: i32 } の時に let s = S::default(); と書いても同じ結果で短いのに let s: S = Default::default(); と書くのはDefaultトレイトのdefault()だと明示するためでしょうか? 結局deriveすると impl Default for S { fn default() -> Self { S { a: 0, b: 0, c: 0 } } } を自動的に定義してくれるという理解であっていますか? 驚いたのは let s = S { b: 123, ..Default:default() }; とすると残りフィールドをデフォルト値展開してくれて S { a: 0, b: 123, c: 0 } が得られることでした そこでderiveを使わずに自分で impl Default for S { fn default() -> Self { S { ..Default::default() } } } と手動かつ内部をDefault::default()に任せてみたところ 再帰しているとコンパイルで警告が出て実行するとコアダンプでしたw なぜ? >>517 Default::defaultはどこでも使えるから癖で使ってる人が多いんだと思う S { b:123, ..Default::default() }は残りのフィールドを展開するというより、 S::default()の所有権を奪ってbだけ書き換えたものを返すという理解が正しい , ..に続くのは構築しようとしているものと同じ型の値 例えばS { a: 123, ..s }のようにも書ける , ..Default::default()と書けばSが期待される箇所なので, ..S::default()と同様になる 以上を踏まえれば最後のコアダンプの原因はS::defaultの無限再帰によるstack overflowだと容易に理解いただけよう >>518 なるほど!よく考えれば let base = S { a: 0, b: 0, c: 0 }; let s = S { b: 123, ..base }; の時と同じstruct base式の構文だったのですね 結局、以下のように自分で展開したところ(当たり前ですが)上手く行きました impl Default for S { fn default() -> Self { Self { a: Default::default(), b: Default::default(), c: Default::default(), } } } Defaultトレイトのdefaultと明示するため、で合ってるよ Arc::cloneにもそのような文化がある >>513 1%のダメな箇所で他の言語の文句言ってるのはrust信者の方ですけどね。 まあ、100%良いものなんてないんだし、子供達がせっかく作ったものを評価し、使ってやるというのも、年長者の優しさってものだろう。 今までどれだけ色々な言語が作られ、流行る、主流になると言われては下火になっていったことかと思えば、Rustもまたいずれ他のものにとってかわられるのが世の流れではあるだろうが、それならそれで良いじゃないか。 諸行無常 >>522 Rustを置き換えるにはコンパイル時点でのメモリ安全性保証を実現しないといけない Rustは諸問題を解決してしまったので代わりの言語は数十年出てきそうにない もし出てきたときには手続き型ではなくなってるだろう >>524 ボンクラPGは排除できるから意外と良い選択かもw みずほはもっとマクロなレベルでの設計の問題じゃないの知らんけど 昔の 1% は (注意を払うという対処法で) なんとかなったが現代のコード規模の 1% は深刻だという話なんだよ。 静的チェックでその1%が埋まると思ってるのがお気楽だなと思うわ。 usize祭りコネ━━━━(゚д゚;)━━━━!! let mut dp = vec![i32::MAX; n_list.len() + 1]; for &i in &n_list { for j in 0..dp.len() { if dp[j] > i { dp[j] = i; break; } } } let mut cnt = n - dp.iter().filter(|&x| x != &i32::MAX).count(); vscodeでセーブした時に、ifに付けちゃった括弧を外して欲しいんだけど、何をどう設定すればいいの? 処理系の勉強をかねてRustで ttps://www.sigbus.info/compilerbook これをやってみようと思う 序盤で二分木&再帰・・・うへー >>532 二分木はむしろ非再帰で組めといわれたら罰ゲームなんですよ‥‥ なんかこのスレ競プロの厄介な人に乗っ取られた? クソコードを延々と貼り付けてるあたり開き直ったか 競プロは別スレ建てて分離しましょう 競プロの件はいずれもRustを利用&学習する人々にとって役に立たない有害なものばかりでこのスレと別件ですから >>535 いやRustで競プロをする人もいるじゃんね Rustを使用している人は、仕事だけの人、競プロだけの人、仕事でも競プロで使う人、のそれぞれの合計 ということは、そこから競プロを排除するってことは、より少ない人数だけを対象にするスレを立てるってことだから、 競プロの話題を禁止したい人が、「Rust原理主義者スレ」とでもして、自分たちが別スレをたてて 原理主義者たちだけで移動するのが論理的かつ合理的ヽ(´ー`)ノ >>537 あなたはまず何の説明も無しにコード貼り散らかして祭りだとか言うことの目的を教えなさいよ ブログトップにキモい自撮り写真貼ってるやつを見てから 競プロ臭のくっさいコードはスルーすることに決めてる >>538-540 スレッドは知識の集合知である場所だと思うから、 B木を考えても、情報が細分化される場合には、 携わる人数(情報)が少ないほうを葉にするのが妥当だと思うけど >>539 Rustにはメリットもあるし、デメリットもある 様々な側面から、こういうことがあり得るとか、こういうこともできるとか そういう情報がプラスになるんじゃないかと思っている 仕事のみの人にとっては競プロの書き方は我流だと思うだろうし、 競プロでも書いている人は、別に仕事で競プロの書き方はしてないが 直感的にやりたいことができないこともあるという思いもある そのあたりの折り合いを付けるのが正しいRustスレなんだと思うんだよね。個人的に。 だから競プロ以外の話をしたいなら、原理主義スレを立てればいいし、 競プロだけの話をしたいなら、競プロスレを立てればいい。 ただし、ここはRustのrootだと解釈している ってことで以降は競プロ禁止 やりたい人は競プロのスレで >>542 そういう強権的なやり方は嫌われると思う >>541 要はフィードバックが欲しくてソース貼ってるのか? ならせめて入力仕様と出力仕様くらいは書こうな 競プロなら問題へのリンクでもいい codeLLDBを消去しやがるからavastアンインストールしてやったわ >>541 添削しました。お納めください。 1. Cをそのままコピペしただけじゃねえか Rustの機能を試すだぁ?enumもtraitもパターンマッチも使えないのに何が検証だ馬鹿野郎 「Cコピペしたけどメリット無いね!」って後何回繰り返すんだ? 2. なんだこの察してちゃんなコードは。保育園にいるつもりか? 意図の明確なコードが1行も無いんだが? 3. お前がここにゴミを貼る妥当性が一つも無い Rustの世界に持ってきた概念のどれも使わないで、何が検証できると思ってるんだ? 例えるなら「ひらがなしか知らない外国人が日本語の良し悪しを検証します!」っていうもんだぞ 誰がマトモに付き合うんだ? >>529 CやC++だと非安全コードはどこにでも現れる可能性があるので100%のコードを人力で確認する必要があったが rustでは安全性に関してはunsafeな部分のみ(例えば全体の1%)を確認すれば良いという話では 静的チェックで100%なんとかしようという話はしていないと思うが そうだなーと思う反面unsafeだらけのコードを目の前にしてげんなりする未来も見えるという… ほとんどの用途でunsafeを直接使うことは無いんじゃない? グローバル変数はOnceCellで解決してしまったし もし生ポ操作するとしたら新たな型を作ってその中に閉じ込める そういうコードが書ける事が問題だとあれほど批判してたのに >>551 それは何も問題ではないよ 例えばVec型もpushやpopですら内部はunsafe利用だけど我々はそれを知らず気にせず安全に使うことができる そもそも競プロにメモリ安全性とかいらないしC++で書いといてくださいよ Rustの良いところはメモリ安全だけではなかろう? 機能性で言えば競プロに必要なものは大抵の言語が備えてるだろうし 使いやすさで言えばRustはきっちり書くことを求められてるから素早く書くのには向いてないし それでも敢えてRustを選ぶ理由は趣味や慣れくらいなのでは releaseビルドするとTrojan:Script/Wacatac.B!mlを検出して Windows Defenderに怒られる --release付けないと大丈夫 誤検知かな? >>553 ごめん 例えばUnsafeCellの存在はRustの借用ルールに制約されることなく自由に新たな型を設計して作る道を開いているけど あくまでも安全な型を作るための素材であって具体的にはRefCellやOnceCellなどの様々な安全な型を提供する素材となっているように unsafeの存在も上位レベルで安全な関数やモジュールを提供するための素材としてのみ用いるべきではないか ということを伝えたかったのです つまり競プロ君のunsafeの使い方はただ危ない逸脱のみであり、 安全かつ便利な何かを提供する目的のための使い方ではなく、 Rustの精神に反している、と。 したがって競プロの話は、 このRust本スレでやるべきことではなく、 ここでは禁じて別スレでやるべき、と。 >>559 競プロくんを競プロの代表扱いするのはさすがに競プロの人に失礼では Rustの精神とかそんな大層な話でもないでしょ 建設的に話せない奴に付き合う必要はないというだけ >>558 違う人が書いた事を、さも自分が書いたように返答するのはどうかと思う >>562 え?? >>558 は自分の意見を書いただけでこのスレにしか書いていないし参考にしたサイトや書き込みもないよ もし偶然にそっくりな内容なものがどこか他にあるなら見てみたいので教えて >>559 こういう自分の意見にあわないと何でも排除したいヤツはどこにでもいるんだよなあ Range関連での質問です (Included(&x), Included(&y)) はx..=yと書けますが、 (Excluded(&x), Included(&y)) を似たように書く方法ってありますか? >>565 ないんじゃない? (3..=5).skip(1)で、妥協するかなぁ Range はよく使うから構文糖を入れてちょっと簡単にするという判断がうまれたんだと思うんで、 それほど頻出しないパターンは明示的に書くしかしょうがないと思う。 自分のプログラムでよく使うのであればそういう関数を用意しておけというくらいの妥協になる。 >>565 range式も魔法があるわけではなく それぞれ対応する構造体があって各traitなどを実装してるだけなのですが stdにあるのは以下の6種類のみですね assert_eq!(.., std::ops::RangeFull); assert_eq!(3.., std::ops::RangeFrom { start: 3 }); assert_eq!(..7, std::ops::RangeTo { end: 7 }); assert_eq!(..=7, std::ops::RangeToInclusive { end: 7 }); assert_eq!(3..7, std::ops::Range { start: 3, end: 7 }); assert_eq!(3..=7, std::ops::RangeInclusive::new(3, 7)); 例えば開始点のあるRangeFrom・Range・RangeInclusiveはIteratorも実装 一方でその(Excluded(&x), Included(&y))形式すなわち (Bound<T>, Bound<T>)および(Bound<&'a T>, Bound<&'a T>)型だと 実装されているのはRangeBoundsトレイトのみでIteratorトレイトなどは無いという違いがあるようです 開始がUnboundedだと意味がないからでしょう つまりイテレータで回したい時にはこの形式では使えないので (Excluded(x), Included(y)) は (x+1)..=y と書くしかないと思います もちろんSkip構造体のコストを払って(x..=y).skip(1)もアリです >>566 >>568 すみません、言葉足らずでした BTreeMap/Setのrangeメソッドに渡す引数を意図していました こちらに渡すのはイテレータではないのでskip(1)はできないようです >>567 >>568 あまり頻出ではないですし仕方ないですかね 実際困るわけではないのですが、 アンバランスなので気になってしまいました ttps://lkml.org/lkml/2021/7/7/349 完全にストップしたな。最低だよ。 Rust for Linuxに関しては結局それ以降進展無しということ? そりゃ普段の作業はGitHub上でやって、まとまったところでパッチ投げるんだから LKMLで日々の進捗報告なんかしたら迷惑でしかない いや実際のドライバーが動かないのにごねてるだけやん。。話になってないんだが。 as usize祭りの回避ができてきてる━━━━(゚∀゚)━━━━!! let mut heap: BinaryHeap<Reverse<(usize, usize)>> = BinaryHeap::new(); heap.push(Reverse((0, 0))); while let Some(Reverse((_, now))) = heap.pop() { let mut que: VecDeque<(usize, usize)> = VecDeque::new(); que.push_back((now, 0)); while let Some((next, cnt)) = que.pop_front() { if cnt == price[now].1 { break; }; for &i in &list[next] { if total[i] > total[now] + price[now].0 { total[i] = total[now] + price[now].0; heap.push(Reverse((total[i], i))); } que.push_back((i, cnt + 1)); } } } VSCodeか何かで、編集中のファイルを(保存する度ではなく)リアルタイムで構文チェックしてもらうことってできないの? 目が悪いもので、C#みたいに間違えたら即指摘みたいなのがすごく助かるんだけど・・・・ ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる