1 名前:デフォルトの名無しさん mailto:sage [2021/11/07(日) 10:04:59.35 ID:pJhT3MIE.net] 公式 https://www.rust-lang.org/ https://blog.rust-lang.org/ https://github.com/rust-lang/rust Web上の実行環境 https://play.rust-lang.org 日本語の情報 https://rust-jp.rs/ ※Rustを学びたい人はまず最初に公式のThe Bookを読むこと https://doc.rust-lang.org/book/ ※Rustのasyncについて知りたければ「async-book」は必読 https://rust-lang.github.io/async-book/ ※C++との比較は専用スレへ C++ vs Rust https://mevius.5ch.net/test/read.cgi/tech/1619219089/ ※次スレは原則>>980 が立てること 前スレ Rust part12 https://mevius.5ch.net/test/read.cgi/tech/1629813327/
231 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 22:02:05.25 ID:s7fhQ2Tk.net] >>224 ・lineの寿命はif-let式の寿命と一致する ・ブロックの最後の文の寿命はブロックを囲む文の寿命と一致する という仕様になっていると思われる 型は関係なくてブロック内の最後の式か否かが重要
232 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 22:26:55.08 ID:hx6pGpzB.net] >>226 >このように2行へ書き換えるとコンパイルが通ります >let x = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>(); line.splitnでborrowしたものを使ってるtemporaryは let xで受けたタイミングでtemporaryじゃなくなる (エラーメッセージにあるdropped soonerの状態になってる) if式がブロックの最後の式でそのif式の一部がborrowを使ってるtemporary セミコロンがないとtemporaryが解放される前にローカル変数のlineが解放されるからライフタイムのエラー そのうち修正されるかもしれないけど今はそういう動きってこと
233 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 22:31:28.50 ID:hx6pGpzB.net] >>226 >let x = line.splitn(3, ' '); >if let [_first, _second, _rest] = x.collect::<ArrayVec<_, 3>>()[..] {}
234 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 22:35:06.87 ID:hx6pGpzB.net] すまん、投稿ミス。 値を返したいときはセミコロンを追加するだけじゃだめだから 一旦変数で受けてからその変数をブロックの最後に書く
235 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 22:39:09.24 ID:8WvE/rry.net] ふむむ lineがヒープにあると以下の2行だけでセミコロン付けろエラーになりますね let line = String::from("A B C D E"); if let [_first, _second, _rest] = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>()[..] {} このif let文を例えば以下のように変えるとセミコロンを付けなくても通るのはどうしてでしょう? if let Some(_s) = line.get(3..6) {}
236 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 22:41:34.40 ID:rIKeeiBO.net] なんでセミコロン付けると一時オブジェクトの寿命変わるんだって思ったけどそういえばC++にもそんな仕様あったな…… 完全式じゃなくて戻り値に使うから破棄されないってことか
237 名前:デフォルトの名無しさん mailto:sage [2021/11/30(火) 23:55:05.80 ID:Y6JwF3m3.net] >>230 ブロックの最後で返す値は変数に入れなくても複雑な式でも大丈夫ですよ
238 名前:デフォルトの名無しさん mailto:sage [2021/12/01(水) 12:41:12.28 ID:KNT1MQhQ.net] なんでBufReadトレイトはあるのにBufWriteトレイトは無いんですか?
239 名前:デフォルトの名無しさん mailto:sage [2021/12/01(水) 13:25:08.66 ID:2cjkBPbo.net] >>231 詳しく知りたければまずはここ↓だけど https://doc.rust-lang.org/reference/destructors.html 言語自体をいじりたいわけじゃなければ あんまり深追いしても役に立たないよ
240 名前:デフォルトの名無しさん mailto:sage [2021/12/01(水) 16:06:22.55 ID:oI4zTDt2.net] >>234 BufReadはReadに対して追加の機能(行単位の読み込みなど)があるけど Writeに対して追加すべき機能がないからBufWriteは存在しないのではないかと思われる
241 名前:デフォルトの名無しさん mailto:sage [2021/12/01(水) 21:58:24.00 ID:QwFnQ8Qa.net] flushしなけりゃ下のレイヤのどこかで勝手にバッファリングされることがほとんどだから用意する意味がないんだろな。
242 名前:デフォルトの名無しさん mailto:sage [2021/12/01(水) 23:34:44.63 ID:hYYowF9a.net] >>237 いやBufWriteトレイトが存在しないだけであってBufWriterはちゃんとある そしてBufWriterがバッファリングする最後の要 誰かが勝手にバッファリングしてくれることはない 例えば何行もファイルに書き込む時にBufWriter使わずに各行毎にwriteしてたら遅くなる
243 名前:デフォルトの名無しさん mailto:sage [2021/12/03(金) 14:04:46.92 ID:xjf4hyRh.net] https://crates.io/crates/rust-script とか https://crates.io/crates/runner みたいなの使ってる人おる? これ使うくらいならLL使うとは思うが
244 名前:デフォルトの名無しさん mailto:sage [2021/12/03(金) 14:45:17.46 ID:RidNMi7I.net] REPL的にコードスニペットの実行確認するために使ったりはできるのかな 今はplaygroundで事足りているが
245 名前:デフォルトの名無しさん mailto:sage [2021/12/04(土) 15:22:12.31 ID:f29/w5s1.net] Read::read_to_end()に空のVecを渡した時に戻り値のusizeとVecのlen()が違う値になる事って有り得ますか?
246 名前:デフォルトの名無しさん mailto:sage [2021/12/04(土) 23:32:14.41 ID:VZLpyp2B.net] 同じと思う let file_size = file.metadata().map(|m| m.len())?; let file_pos_before = file.stream_position()?; let read_buf_size_before = read_buf.len(); このようなfileとread_bufがある任意の状況で let read_size = file.read_to_end(&mut read_buf)?; とread_to_end()すると以下が常に成り立っていると思われる assert_eq!(read_buf_size_before + read_size, read_buf.len()); assert_eq!(file_pos_before + read_size as u64, file_size);
247 名前:デフォルトの名無しさん mailto:sage [2021/12/05(日) 23:43:02.39 ID:+2NbegRW.net] > loop式はbreakで指定した値を返せるのに > なぜwhile式やfor式は値を返せないの? > Option型にしてbreakで値を指定した時だけSome(値)としてそれ以外はNoneとすれば便利なのに そのloopと組み合わせればよい (例) let r = 'result: loop { for x in 1..100 { for y in 1..100 { if x * y > 1234 { break 'result Some((x, y)); } } } break 'result None; }; assert_eq!(r, Some((13, 95)));
248 名前:デフォルトの名無しさん [2021/12/06(月) 12:54:15.14 ID:BduPW1Ae.net] >>243 forよりイテレータを繋げた方が単純でわかりやすいよ!と言おうとしたら let r = (1..100) .map(|x| (1..100) .map(|y| (x, y)) .find(|(x, y)| x * y > 1234) ) .find(|o| o.is_some()) .map(|oo| oo.unwrap()); assert_eq!(r, Some((13, 95))); むしろ複雑でわかりにくくなってしまったw まさかの>>243 のダミーloop使用がベストアンサーなのか!?
249 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 13:12:38.43 ID:PE/XVSQC.net] >>244 flat_mapを使えば良い let r = (1..100).flat_map(¦x¦ (1..100).map(¦y¦ (x, y))).find(¦(x, y)¦ x * y > 1234);
250 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 13:28:57.99 ID:GjZweGXf.net] どれもこれも分かりやすいとは思えない
251 名前:デフォルトの名無しさん [2021/12/06(月) 15:59:22.06 ID:BduPW1Ae.net] 結局見やすくこう書けるといいんだよね let r = pair(1..100, 1..100).find(|(x, y)| x * y > 1234); assert_eq!(r, Some((13, 95))); これでassertも通ったけどyのイテレータとx自身の2ヶ所にCloneが必要となってしまった 避けられないような気がするけどどうでしょうか? fn pair<IX: Iterator<Item=X>, IY: Iterator<Item=Y> + Clone, X, Y>(ix: IX, iy: IY) -> Pair<IX, IY, X, Y> { Pair { cur_ox: None, cur_iy: iy.clone(), ix: ix, iy: iy, } } struct Pair<IX: Iterator<Item=X>, IY: Iterator<Item=Y>, X, Y> { cur_ox: Option<X>, cur_iy: IY, ix: IX, iy: IY, } impl<IX: Iterator<Item=X>, IY: Iterator<Item=Y> + Clone, X: Clone, Y> Iterator for Pair<IX, IY, X, Y> { type Item = (X, Y); fn next(&mut self) -> Option<Self::Item> { loop { if let None = self.cur_ox { self.cur_ox = self.ix.next(); } if let Some(ref x) = self.cur_ox { if let Some(y) = self.cur_iy.next() { break Some((x.clone(), y)); } else { self.cur_ox = None; self.cur_iy = self.iy.clone(); continue; } } else { break None; } } } }
252 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 16:01:51.04 ID:NQsvo9rr.net] 最近知ったボクの大発見書いていい? let a: Option<i32> = None; これは let a = None::<i32>; と書ける 関数のパラメータとして渡そうとして f(None)で怒られたとき f(None::<i32>)として怒られない しょうもないレス失礼いたしました
253 名前:デフォルトの名無しさん [2021/12/06(月) 16:21:14.38 ID:BduPW1Ae.net] >>248 曖昧性を確定させる::<型>の指定は色々なところで出てくるね 例えばcollect::<Vec<_>>()とか ブロックやクロージャの返り値でOk::<(),std::io::Error>(())とか
254 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 16:35:36.71 ID:McsJgKJD.net] >>247 itertoolsのcartesian_productがほぼそれ
255 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 17:07:16.47 ID:+ZC47hZJ.net] iproduct!
256 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 17:09:45.91 ID:Fu08U5Ef.net] >>248 型パラメータは Option のパラメータなので順当に考えれば Option::<i32>::None と書くべきだし実際にそれで通るんだけども、 歴史的経緯でバリアントにも付けられるようになってる。 短く書けるから習慣的にはバリアントに型を付けるほうが多いかな……?
257 名前:デフォルトの名無しさん [2021/12/06(月) 17:31:38.25 ID:BduPW1Ae.net] >>250 なるほど直積集合かぁ 同じくyのイテレータとxはCloneを要求してますね fn cartesian_product<J>(self, other: J) -> Producfgt<Self, J::IntoIter> where Self: Sized, Self::Item: Clone, J: IntoIterator, J::IntoIter: Clone,
258 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 20:06:32.13 ID:NQsvo9rr.net] >>249 > Ok::<(),std::io::Error>(())とか 正直見たことなかったです >>252 > 歴史的経緯でバリアントにも付けられるようになってる。 (´・∀・`)ヘー そういうわけなんですね
259 名前:デフォルトの名無しさん [2021/12/06(月) 21:47:08.33 ID:BduPW1Ae.net] >>254 例えばlet x = spawn(async { ... });して裏で何か処理をやらせといた結果を 後でもしエラーが出ていたら進めちゃいけないタイミングでx.await?;で確認するわけだけど spawnが返す型をxに律儀に記述するのは面倒なのでそこは略すとして asyncブロック内で?とOk(())だけ書くとコンパイラが文句を言うので仕方なく記載
260 名前:デフォルトの名無しさん mailto:sage [2021/12/06(月) 22:11:44.75 ID:NQsvo9rr.net] なるほど勉強になりました
261 名前:デフォルトの名無しさん mailto:sage [2021/12/07(火) 21:26:04.18 ID:pFZAiCY5.net] 12次元までならiproduct!が使える use itertools::iproduct; let r = iproduct!(1..100, 1..100).find(|(x, y)| x * y > 1234); let r = (|| { for (x, y) in iproduct!(1..100, 1..100) { if x * y > 1234 { return Some((x, y)); } } return None; })();
262 名前:デフォルトの名無しさん [2021/12/08(水) 14:18:48.01 ID:6NuoEm2L.net] ARM版のWindowsでRustのコードを書くのってめんどくさいな 生のWindowsで使用する場合、VisualStudioに付属するx86用のリンカーが非推奨警告を無視すれば使えたものの、次期バージョンからx64専用になってしまうっぽい 一方、仮想環境等+VSCodeでは、RustAnalyzer等が機能せず苦労する・・・・ 持ち運び用にケチってMacを買わなかったのが大問題だった、なんかいい方法ないのかな?そもそもARM Windowsで動くリンカーってVisualStudio付属のものしかないのかな? ケチったって言ってもよくよく考えてみると大して金が浮いてもないし、変なもん買っちまった
263 名前:デフォルトの名無しさん mailto:sage [2021/12/08(水) 14:36:22.94 ID:W5vI+s6z.net] >>258 i686ターゲットのバイナリをバイナリ変換で動かしてるってこと? aarch64-windowsターゲットとARM用のリンカ使えばネイティブのARMバイナリできるんじゃないかと思うけど
264 名前:デフォルトの名無しさん [2021/12/08(水) 20:15:10.58 ID:pzF9gjPk.net] バイナリバイナリルルルルルー。
265 名前:デフォルトの名無しさん mailto:sage [2021/12/08(水) 21:25:01.32 ID:t4Pzut9P.net] rustはどんどん新しい機能が追加されていくのはいいけど、 後方互換性を気にして過去に追加された「間違った」機能を削除するという 思い切ったこともやって欲しいな これまでの言語は後方互換性にとらわれて滅茶苦茶になってるから
266 名前:デフォルトの名無しさん mailto:sage [2021/12/08(水) 21:29:04.83 ID:ff6DaDGr.net] >>261 C++かな?
267 名前:デフォルトの名無しさん mailto:sage [2021/12/08(水) 21:44:15.05 ID:tBq4QMAR.net] >>261 editionでは物足りない?
268 名前:デフォルトの名無しさん mailto:sage [2021/12/08(水) 21:50:49.56 ID:t8qOOWvR.net] 実際2021editionではレンジパターンの ... が削除されて ..= に一本化された
269 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 08:53:14.94 ID:sqaPNXyj.net] >>258 今どきDocker使うのはデフォだから何の問題もない、因みにRustAnalyzerも使える 使えないのは、復数のプロジェクトが見える状態にしてるから 今どき復数ウィンドウ立ち上げても何の問題もない、ルートフォルダを固有にしたら解決 つまり、調査不足が原因
270 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 10:59:17.60 ID:4q0mFQ+L.net] ARM は安物のイメージがある。 WSL2, Linux, Docker, VSCode とか使えるのかな? Mac も、M1 に変わったから
271 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 11:10:00.09 ID:XwSSuf4e.net] 原理的には ARM
272 名前:フほうがインテル系 (もはや AMD 系と呼ぶべきか) よりも高速化できる可能性があるとは言われている。 今以上に回路を細かくするのは無理というところまできてしまっているのでアーキテクチャのほうで見直しが必要なんだが インテル系は互換性が足かせになってしまっていてあまり思い切ったことが出来ない。 現時点はインテル系向けにチューニングされたソフトウェア資産が多いから上手くいっているけど将来もそうとは限らない。 [] [ここ壊れてます]
273 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 11:45:18.26 ID:t4DQqTrM.net] >>267 スレチだけどその話の出展あったら教えてほしい
274 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 14:22:31.39 ID:RSXecyhf.net] CISCRISCの話じゃなくてメモリモデルの話ならそうかなって思う 今のx64って実質中身RISCって聞いたことあるし Rustで言うとx64では全部SeqCstとして扱われるみたいな話
275 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 17:42:03.96 ID:VJ9QB09P.net] リソースの話だけなら命令デコーダーとか? x86_64は拡張や互換性とか可変長命令だったりで無駄にトランジスタ消費するのが電力性能比的に足かせみたいな
276 名前:デフォルトの名無しさん mailto:sage [2021/12/09(木) 20:39:08.00 ID:0MvTGuxY.net] 今どきのプロセッサだと分岐予測器やキャッシュが支配的でデコーダなんて誤差だと思う あと可変長は命令側の帯域やキャッシュ効率が良くなるという面もあってRISC系でも採用してることが多い 結局両者とも長年の改善で似たようなとこに落ち着いてるわけで、ISAが違うからどうこうみたいな話は結構眉唾
277 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 19:08:58.23 ID:oic9EtmK.net] こういうことをしたいのですがコンパイルエラーとなってしまいます const DEFAULT_NAME: &str = "namae"; let arg1: Option<String> = std::env::args().nth(1); let name: &str = arg1.map_or(DEFAULT_NAME, |s| s.as_str()); どう直せばよいでしょうか?
278 名前:デフォルトの名無しさん [2021/12/11(土) 19:10:55.89 ID:ZSpAs+oG.net] namaeじゃなくてnameな aが余計 この程度の英語のスペル書けないとかプログラミング向いていないしやめた方がいいよ
279 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 19:21:25.94 ID:UNEoSQah.net] 自演ボケか?
280 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 19:35:01.57 ID:K+rsGRUk.net] >>272 そのままだとarg1が消費されてなくなるのに参照だけ残ることになるからエラー Stringで受ければいいよ let name: String = arg1.unwrap_or(DEFAULT_NAME.to_string());
281 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 20:19:05.99 ID:XRkKLs6o.net] >>273 すげーな。してはいけないレビューの典型例じゃねーか。 すげーな
282 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 20:24:40.06 ID:Z1L5tslT.net] いやネタでしょ
283 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 20:29:51.18 ID:/anFx7me.net] >>275 これだとarg1がSomeの時もto_string()が呼び出されて無駄なヒープアロケーションが走るのでunwrap_or_elseにすべき
284 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 22:35:07.46 ID:oic9EtmK.net] みなさんありがとうございます Stringにする方法は無事にこれで動きました let name: String = arg1.unwrap_or_else(|| DEFAULT_NAME.to_string()); 元の質問>>272 のように&strにする方法は無いのでしょうか? もし可能ならばto_string()のヒープアロケーションを減らせるかなという質問です
285 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 22:59:59.99 ID:yVS9OnV5.net] >>279 Cowかな let name: Cow<str> = arg1.map_or(Cow::Borrowed(DEFAULT_NAME), |s| Cow::Owned(s));
286 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 23:20:49.43 ID:yVS9OnV5.net] 場合によってはこれでもいいのかな? let name: &str = &arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str());
287 名前:デフォルトの名無しさん mailto:sage [2021/12/11(土) 23:54:40.62 ID:tYxQqCnY.net] >>281 それでもよいけど正解はシンプルなこれ let name: &str = if let Some(ref arg1) = arg1 { arg1 } else { DEFAULT_NAME }; まずarg1を消費しないようにrefで受ける 2代目のarg1は&Stringなので自動的に&strへderefされる
288 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 02:10:02.51 ID:h/Sb7JBW.net] 1.40からas_derefっつうのがあるんだってさ let name = arg1.as_deref().unwrap_or(DEFAULT_NAME); でもコマンドライン引数の場合は消費しないメリットがほぼ無いのでCowのほうがいいかな
289 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 04:28:54.46 ID:8d+idsXS.net] どの型で統一すべきかは (1) その後に加工伸長などするならString (arg1をここで&strに統一するのは無駄) (2) 参照するのみなら&str (DEFAULT_NAMEをここでto_stringするのは無駄) (3) その後に判明する条件次第で両ケースありうるならCow (ただし常にCow利用はCowコストが無駄) って感じ?
290 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 10:07:32.08 ID:svMJrknn.net] おそらくその通りだけど、CLIツールの初回一回だけのアロケーションにそこまでこだわるのがそもそも無駄って気もする ループ内とかでもなければ雑にString作っちゃっていいかもね
291 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 10:31:14.68 ID:eE6Pv/WZ.net] んだ
292 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 10:46:59.45 ID:8d+idsXS.net] >>285 今回のケースはそうだね ただしヒープ割り当てをなるべく避ける様々な手法を把握しているか否かは色んな局面で効いてくるから 今回6通りも動くコード例が示されたことは多様に対応可能な柔軟性の良さかな 気にしなくても書けるし気にすれば効率を上げることができる点で
293 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 18:38:25.33 ID:h/Sb7JBW.net] >>284 Cowと&strに揃える場合の一番の違いはライフタイム管理 Stringを&strにするとライフタイム管理がつきまとうから すぐ使いきる場合以外はCowに比べてメンテナンスしにくいコードになる
294 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 18:59:43.58 ID:3rjDzGgS.net] 文字列についてはStringにするかCow<str>にするか迷うくらいならinternしちゃうのも手かと どのライブラリが定番なのかよく知らないけど
295 名前:デフォルトの名無しさん mailto:sage [2021/12/12(日) 19:49:57.76 ID:be4Z/veb.net] >>281 > let name: &str = &arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str()); それarg1の前の&は不要でこれで動く let name: &str = arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str()); さらにas_str()使うより短く書けて&**sで&strになる let name: &str = arg1.as_ref().map_or(DEFAULT_NAME, |s| &**s); さらに&Stringのsのままでもderefされるため大丈夫 let name: &str = arg1.as_ref().map_or(DEFAULT_NAME, |s| s); クロージャが何もしてないからといって無くしてしまうとderefが効かず型不一致コンパイルエラー × let name: &str = arg1.as_ref().unwrap_or(DEFAULT_NAME); そこで明示的にderefしてやればよい let name: &str = arg1.as_deref().unwrap_or(DEFAULT_NAME);
296 名前:デフォルトの名無しさん [2021/12/13(月) 21:23:25.03 ID:zBnuOauJ.net] ken okabeのqiitaの記事がまた炎上してるよ mod_poppoにボコボコにされてる
297 名前:デフォルトの名無しさん mailto:sage [2021/12/13(月) 22:30:34.09 ID:i33Tname.net] あれ、Qiitaには垢バンされて投稿できないんじゃなかった?
298 名前:デフォルトの名無しさん [2021/12/13(月) 23:00:30.90 ID:Yx06Lw1d.net] ググってもよくわからないのですが、どういった方なんですか?
299 名前:デフォルトの名無しさん mailto:sage [2021/12/13(月) 23:30:17.26 ID:IeJGNs4K.net] 盛大な時間の無駄になるだけなので調べてはいけない
300 名前:デフォルトの名無しさん mailto:sage [2021/12/13(月) 23:59:51.20 ID:mqpFvLOG.net] >>291 poppoとかいうやつも多様な定義や多様な解釈が存在している中で不要なイチャモンばかりだな さらに冒頭のこれも > JavaScriptで演算子オーバーロードを実現しようとするのは筋が悪
301 名前:い たまたま例としてJavaScriptを用いているだけなのにそれすら理解できていない okabeは使用言語と無関係に成り立つ話をしてるだろ > reduceは二項演算ではなく三項演算として捉えるべき これも些細なことであって例えばRustなら fold()は『入力列・初期値・演算関数』の三項演算だけど reduce()は『入力列・(初期値は入力列の先頭なので無指定)・演算関数』の二項演算 とはいえokabeの方もイテレータすら扱っていないからイマイチ [] [ここ壊れてます]
302 名前:デフォルトの名無しさん mailto:sage [2021/12/14(火) 00:07:08.47 ID:LYbWtya0.net] Rust関係ねーだろ 二度とその名前を口に出すな
303 名前:デフォルトの名無しさん [2021/12/14(火) 10:41:11.49 ID:QBQJlKEt.net] P2P方式の2D対戦ゲームを作りたいと考えています。 おすすめのゲームエンジンやライブラリはございますか?
304 名前:デフォルトの名無しさん mailto:sage [2021/12/14(火) 11:46:02.04 ID:mpAOsF0a.net] >>297 あくまでゲームを作ることが目的なんだったら普通にUnityとかでいいんじゃない? どうしてもRust使いたいならサーバー側で使えばいい
305 名前:デフォルトの名無しさん [2021/12/14(火) 12:45:44.37 ID:QBQJlKEt.net] >>298 個人的にRustが好きなので技術向上のためにもRustで作りたいと考えています。 現在はAmethystとlibp2pを用いて開発しようと考えているのですが、如何せん知識が浅くこれで目的のものが作れるのか分かりません。 是非先人の知恵をお貸しください。 Rustでの開発にロミオとジュリエットの恋ほどの壁があるという場合は、大人しくC++かUnityで作成します・・・
306 名前:デフォルトの名無しさん mailto:sage [2021/12/14(火) 13:10:49.68 ID:+JRF3Q+g.net] そんだけの情報ではなんともいえん。 見通しが立たないものを試行錯誤で作る場合には モジュールではなくレイヤで分割したほうがいいという考え方がある。 要するに機能不足でもバグだらけでもコードが整理されてなくてもいいからとにかく「動くもの」を作って その上に足りないものをどんどん足していくという方法論だ。 よくわかってないなら小さいもので色々やってみて知識を積み重ねるべきで、 よくわからんまま目的に向かって邁進してもあんまり技術向上にはならんよ。
307 名前:デフォルトの名無しさん [2021/12/14(火) 13:22:32.10 ID:QBQJlKEt.net] >>300 ありがとうございます 色々試してみます
308 名前:デフォルトの名無しさん mailto:sage [2021/12/14(火) 13:53:41.90 ID:ZTFSAiNI.net] >>299 Amethystは開発中止になったから今からやるのは微妙かも gamedev.rsに今アクティブなエンジンやゲームがスクショ付きで載ってるから そこからイメージにあうものを探すといいかもしれない
309 名前:デフォルトの名無しさん [2021/12/14(火) 15:30:19.02 ID:QBQJlKEt.net] >>302 そうだったんですね・・・ 時間は掛かるかもしれませんが、色んなものを試して自分に合う物を探すことにします
310 名前:デフォルトの名無しさん mailto:sage [2021/12/15(水) 07:48:40.06 ID:inpCEPk8.net] 技術を高める目的なら windows-rs や wgpu-rs みたいな一段下から積み上げるのも楽しいよ。 ゲーム作る道のりは遠くなるけど、画面に三角形出したり、キーの入力受け付けたりするだけで達成感が出てくる。
311 名前:デフォルトの名無しさん mailto:sage [2021/12/17(金) 12:43:03.76 ID:jilrKB7M.net] https://forest-watch-impress-co-jp.cdn.ampproject.org/c/s/forest.watch.impress.co.jp/docs/serial/yajiuma/1374/986/amp.index.html エディタ自体はvscodeに勝つの難しそうだがGPUIとやらが定番GUIフレームワークにならないか期待
312 名前:デフォルトの名無しさん [2021/12/17(金) 16:39:33.05 ID:6JlgT7vi.net] 既出だったらすいません 前から疑問だったのですが、出力におけるprint!マクロのような入力用マクロが標準ライブラリに用意されていない理由ってなんですか?
313 名前:デフォルトの名無しさん mailto:sage [2021/12/17(金) 18:11:01.90 ID:tWB5K5S1.net] >>297 1対多で、broadcast するチャットルームのバックエンドなら、 Ruby on Rails 6 のAction Cable(WebSocket)が基本 JavaScript は、React, Phaser とか 【Rails】(送信時のリロード無し!)Action CableでSlack風チャットアプリを作成、2019/12 https://www.youtube.com/watch?v=o6PuxDr8Meg
314 名前:デフォルトの名無しさん mailto:sage [2021/12/17(金) 18:36:09.20 ID:ePonqmC1.net] >>306 この辺読んで https://github.com/rust-lang/rust/pull/75435 https://github.com/rust-lang/rfcs/pull/3196
315 名前:デフォルトの名無しさん [2021/12/17(金) 23:52:56.58 ID:6JlgT7vi.net] >>308 熟読させていただきました。 私としてはたった数十行のコードであること且つ他のほとんどの言語に存在しているものなのであっても良いのかなと思ったのですが、Rustの基本理念を考えると慎重になる理由も理解出来ました。 Rustの経験が浅い私目線ではあまり腑に落ちませんでしたが、皆さんはどう考えていますか?
316 名前:デフォルトの名無しさん mailto:sage [2021/12/18(土) 15:05:52.37 ID:JzdvFl4u.net] 熟読はしてないけど、外部ライブラリで簡単に実現可能であるなら 直感的には、本体メンテナの苦労を増やすほど価値があると思えないし別にいらんかな こういうIOとかCLIプロンプトらへんの機能ってどうしても好みが分かれるというか、 ユースケースによって必要な機能がかなり違ってきちゃうと思うし
317 名前:デフォルトの名無しさん mailto:sage [2021/12/18(土) 20:46:47.80 ID:w6oxugk6.net] C++のiostreamが失敗作だから慎重になるのもわかる笑
318 名前:デフォルトの名無しさん mailto:sage [2021/12/18(土) 23:17:58.09 ID:SfwydFh9.net] >>306 C言語でのprintf相当はあるのにscanf相当がstdにないのはなぜか?ですね 逆になぜprintf相当がRustの標準ライブラリにあるのか?を考えてみると (1) 読み書きの非対称性 人間が読むためにプログラムが書くことはエラー表示を含めて利用必須かつ頻出 一方で人間が書いたものをプログラムが読むことはレア ファイルや通信相手への読み書きは各プロトコル/各API/シリアライズ等で対象外 (2) コンパイラサポート print!やformat!等は頻出するので効率面からコンパイラサポートが効率的 実際にそれらが利用しているformat_args!はコンパイラ内蔵マクロ (3) 標準ライブラリ採用 外部ライブラリで実現可能なものは採用しないが基本 今回はコンパイラ内蔵マクロだから採用 つまり出力は頻度と効率化で採用がクリアされたけど 入力は外部ライブラリで十分かなと
319 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 02:25:28.05 ID:KXG/wmTu.net] しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える
320 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 04:21:35.56 ID:1R2jF/rb.net] 競プロ全然知らないけどstdinに入力数値がくるからか | 入力は以下の形式で標準入力から数値が与えられる。 | a b c d e | 積が奇数なら Odd と、 偶数なら Even と出力せよ。 標準ライブラリだけ使うと毎回こんなの書くのは面倒だもんな | use std::io::{stdin, BufRead, BufReader}; | println!("{}", if BufReader::new(stdin()).lines().next().unwrap().unwrap().split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0) { "Even" } else { "Odd" }); >>313 そのproconioを使うとこうなるようだ | proconio::input! { v: [isize; 5] } | println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" });
321 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 06:54:36.03 ID:KXG/wmTu.net] >>314 ワンライナー大好きかよ
322 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 07:00:31.55 ID:1R2jF/rb.net] >>315 マルチラインだと標準ライブラリだけでもわかりやすくなる?
323 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 08:28:47.39 ID:KXG/wmTu.net] >>316 あいやごめん。proconioのところはどうあがいてもプロコン専用のproconioが一番見やすいよ。それ用に特化されたライブラリだし 俺が大好きかよって言ったのは println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" }); の部分
324 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 09:08:15.26 ID:1R2jF/rb.net] どの言語でも三項演算子(相当)はワンライナーで書くんじゃね?
325 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 09:36:51.21 ID:Tv9xxy1h.net] 見た目汚いなw
326 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 09:42:08.31 ID:1R2jF/rb.net] これでいいかね? println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" });
327 名前:デフォルトの名無しさん [2021/12/19(日) 09:57:56.98 ID:KXG/wmTu.net] 俺ならこんな感じかなあ 俺は頭悪いから、途中結果に一つ一つ名前つけないとわかんなくなっちゃうわ まあワンライナー見た時に「グエー」って思っただけだからごめん。「大好きかよ」とかいっておいてなんだけどあんま気にしないで use proconio::input; fn main() { input!(v: [usize; 5]); let is_even = v.iter().any(|x| x % 2 == 0); let result = if is_even { "Even" } else { "Odd" }; println!("{}", result); }
328 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 10:13:36.41 ID:1R2jF/rb.net] >>321 なるほど じゃあ最初の標準ライブラリのみはどのように分けるのかな println!("{}", if BufReader::new(stdin()).lines().next().unwrap().unwrap().split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0) { "Even" } else { "Odd" });
329 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 10:17:01.07 ID:KXG/wmTu.net] >>322 proconio使うw Rustで競プロするにはIOごときに専用ライブラリ使うことになってなんかなあって思うけど、そう思いながら使う
330 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 12:54:53.29 ID:XhCh7cuL.net] >>315 ワンライナーやクロージャでまとめて書くと所有権やライフタイムの問題が出にくいんだよ 他の言語と違ってRustで適切に分割して読みやすく書くのは初心者には難しい
331 名前:デフォルトの名無しさん mailto:sage [2021/12/19(日) 13:44:27.43 ID:JD8Mu2Jr.net] わけわからんくてビビってたらよく見るとPythonスレじゃなかった