Rust part13at TECH
Rust part13 - 暇つぶし2ch144:デフォルトの名無しさん
21/11/26 11:44:41.28 kuMbCEJE.net
>>139
二重指定は一方でtrue一方でfalse指定しているパターン

145:デフォルトの名無しさん
21/11/26 12:05:35.16 SqSfLhr2.net
>>132
どうやったら綺麗なのか参考のため教えて
Rustじゃなくて他の言語でも
仮想の言語でもいいよ

146:デフォルトの名無しさん
21/11/26 12:25:05


147:.02 ID:kuMbCEJE.net



148:デフォルトの名無しさん
21/11/26 12:29:19.27 kuMbCEJE.net
これが美しいと言う人はそれこそ逆ポーランド次元から来た異次元人だと思うよ

149:デフォルトの名無しさん
21/11/26 12:40:54.22 R0yJ4Kup.net
なかなか極端な例を出してきたな……

150:デフォルトの名無しさん
21/11/26 12:43:09.59 GoGODfBQ.net
おまいら日本語否定ですか。

>>144は設計が悪いんじゃない?
File::options().readwrite().newfile().open("foo.txt”);
なら自然だろ。
>>144

151:デフォルトの名無しさん
21/11/26 12:51:53.22 kuMbCEJE.net
逆ポーランド人現る

152:デフォルトの名無しさん
21/11/26 12:53:26.61 kuMbCEJE.net
ファイルを開こうと思うときにoptions型から思考がスタートする人は天才なんだろうな
それか飼いならされた人

153:デフォルトの名無しさん
21/11/26 12:57:20.12 kuMbCEJE.net
言語否定じゃなくてライブラリ設計がおかしい
実用無視の人が設計するとこうなる

154:デフォルトの名無しさん
21/11/26 12:58:29.05 Q6WyUjPa.net
File::open_with_options("foo.txt", &OpenOptions::new().read(true).create(true));
どっちが良いとか悪いとかじゃないと思うがなあ

155:デフォルトの名無しさん
21/11/26 13:13:18.47 kuMbCEJE.net
美しくないだろ普通に

156:デフォルトの名無しさん
21/11/26 13:13:45.37 HMe+psgI.net
OpenOptionsって名前で明らかに「ファイル開く時のオプションですよ」って名前なのにファイル開く操作まで持ってるから気持ち悪いんだよな
同じモジュールでディレクトリはDirBuilderとかあるんだから普通にFileBuilderとかにすりゃええやんとか思っちゃうけどなんか理由があったんかね

157:デフォルトの名無しさん
21/11/26 13:23:36.09 kuMbCEJE.net
確かに他だったらoptionのインスタンスを作ってopenに食わせる感じだな
それもどうかと思うけど
ほぼ定数みたいなものをわざわざ作って食わせるなんて

158:デフォルトの名無しさん
21/11/26 14:04:50.29 TIzT5fn9.net
慣れない人にとっては分かりにくいAPIにならざるを得ないのは確か
ただ他の言語でオプション引数やオーバーロードが2桁あるのが当たり前になってるようなライブラリを見るとそれぞれ一長一短あるなとは思う

159:デフォルトの名無しさん
21/11/26 14:15:29.08 Q6WyUjPa.net
>>154
associated constくらい用意してもらってもいいかもね

160:デフォルトの名無しさん
21/11/26 14:20:28.16 Ye0bskEh.net
>>153
OpenOptionsはrust1.0以前からあるものなのでその頃はビルダーのイディオムがなかったのだと思う
DirBuilderはrust1.6で追加されたものなので比較的新しい

161:デフォルトの名無しさん
21/11/26 14:57:24.65 AxmLr4ZJ.net
> 通常のCのオープン関数のほうが100倍キレイで簡潔で合理的
さっぱりわからんけどw
別に
File::options().readwrite().newfile().open("foo.txt”);
がいいとも悪いとも思わんし
cのopenがいいとも悪いとも思わん
どんな素晴らしいopen見せてくれるのかと思ったらガッカリした

162:デフォルトの名無しさん
21/11/26 15:03:20.08 BGloBCeB.net
OpenOptionsが分かりにくいってのはそのとおりだと思うし、実際みんなそう思ってるみたいで
ちょうどFile::optionsにするRFCが通るところだよ

163:デフォルトの名無しさん
21/11/26 16:18:02.52 Ye0bskEh.net
>>159
stabilizeのPRが10日前に取り込まれたから1月にはリリースされそう

164:デフォルトの名無しさん
21/11/26 18:16:06.66 kuMbCEJE.net
>>158
FILE * fopen(const char * filename, const char * mode);
こっちの方が100倍良い

165:デフォルトの名無しさん
21/11/26 19:18:40.42 wVYXipKz.net
>>161
それはfopenの仕様(引数の意味とか)を知っているのが前提だからなぁ。
filenameとmodeの順番を間違えたら読み間違える。
メソッドチェーンと比較するなら名前付き引数のメソッド呼び出しじゃない?
あるいはインテリセンス環境下という条件付きか。

166:デフォルトの名無しさん
21/11/26 19:21:46.75 Hq7eoo6P.net
>>161
ほんそれ

167:デフォルトの名無しさん
21/11/26 19:26:21.35 kuMbCEJE.net
仮想のコードで例が適切かどうかわからないけど
File::options().readwrite().newfile().read().open("foo.txt”)
と書いて直後で書き込めねえええええよと叫ぶよりfopenの方がいいだろ;

168:デフォルトの名無しさん
21/11/26 19:37:54.04 kuMbCEJE.net
あ、ミスった

それはさておき例のメソッドチェーン見ても瞬時に不安しかよぎらない
readwrite() が中で read(true).write(true) してるとして
readonly() が中でread(true)しかしてないんじゃないかとか不安

169:デフォルトの名無しさん
21/11/26 19:47:03.96 AxmLr4ZJ.net
>>162
> 名前付き引数のメソッド呼び出しじゃない?
俺も最初はそう言う話が出てくるのかとおもったら
cのopenを有りがたがってる奴が出てきて呆れた

170:デフォルトの名無しさん
21/11/26 20:09:04.42 XtGzaRsE.net
>>134
メソッドチェーンと関数チェーン|パイプラインが区別できてないんでは?
メソッドチェーンってレシーバの記述を省略できるとか文の数が減るとかでしかないでしょ。

171:デフォルトの名無しさん
21/11/26 20:37:35.34 kuMbCEJE.net
>>166
fopenとゴミみたいなメソッドチェーン
どっちがバグの温床だ?

172:デフォルトの名無しさん
21/11/26 20:42:02.78 kuMbCEJE.net
cのfopenはメソッドチェーンより簡潔だ
本当は他の言語のenumでいいんだけど
Open("rust.txt",FileMode.Open, FileAccess.Read)
これでバグは出ない

173:デフォルトの名無しさん
21/11/26 20:55:25.49 R0yJ4Kup.net
そんなに変わらへんやん、むしろuseで引き込む名前が増えて美しくないやん

174:デフォルトの名無しさん
21/11/26 21:02:27.39 Ye0bskEh.net
foo(true, false, true, false) や foo(None, None, None, Some(true)) みたいな呼び出しよりは100倍マシ

175:デフォルトの名無しさん
21/11/26 22:47:08.22 r6ugNRE0.net
ところでreadwrite()とかnewfile()ってなんですか?

176:デフォルトの名無しさん
21/11/27 00:09:21.90 riEP2Tv6.net
OpenOptionsの名称問題はともかく
なぜメソッドをチェーンさせているかというと理由は明白で
OpenOptionsExtトレイトをuseすると使えメソッドが拡張されて.mode()などが使えるようになるからだよ

177:デフォルトの名無しさん
21/11/27 00:15:29.99 4eTYjVC9.net
パイプ演算子は |> いつ実装されるの?

178:デフォルトの名無しさん
21/11/27 00:19:05.68 L+2AsAAt.net
どうせ上のtimes()トレイト君でしょ

179:デフォルトの名無しさん
21/11/27 00:42:49.16 w5eY7K13.net
チェーンの話なら、出来るだけチェーン派が多いけど.NETのLINQみたいになったら嫌?
それとも歓迎?LINQ形式のほうが分かりやすい。前の高階関数の話もそうだけど…
OpenOptionsはなんでもかんでもトレイトの弊害の気もする
articles =
  from a in articles
  orderby a.published descending
  select new article_st;
URLリンク(github.com)
let e: Vec<i32> = linq!(from p in x.clone(), where p <= &5, orderby -p, select p * 2).collect();
このプロジェクトはcloneしてしまうところがダサいが、MSが参画しているということはありうるわけで

180:デフォルトの名無しさん
21/11/27 00:54:31.43 tWlgYd9Y.net
>>173
元がこうだもんな
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
そしてunix以外にも対応するために
std::os::unix::fs::OpenOptionsExtへ分けたのだろう
このメソッドチェーンビルダー方式以外のAPIでは詰む

181:デフォルトの名無しさん
21/11/27 05:50:15.37 IOkCeWcH.net
>>176
LINQはSQL風になる糖衣構文だからちょっと違うんちゃう。Rustに導入されても�


182:シの世界感と異質だし……。 個人的にはあれがSQL屋以外に直感的とは思えないw



183:デフォルトの名無しさん
21/11/27 09:55:26.18 sBo289Q7.net
>>174
rustは第一引数がselfの場合にメソッドのレシーバーになるのだから、実質パイプライン

184:デフォルトの名無しさん
21/11/27 11:01:40.71 kX7QbhiL.net
それはElixirと同じ「なんちゃってパイプライン」でメソッドチェーンが実現できるというだけでは。
ここで欲しいと言われているのは大元のF#のように自由関数やその部分適用が使えるパイプラインのことだろう。

185:デフォルトの名無しさん
21/11/27 12:26:31.88 Xdw8IP3R.net
自由関数?

186:デフォルトの名無しさん
21/11/27 14:14:35.41 A1VfIYPt.net
第一引数がselfとかじゃないやつのことじゃね

187:デフォルトの名無しさん
21/11/27 15:58:50.40 lc2cVbH3.net
自由関数ってなんだっけ?
自由変数ならわかるんだけど

188:デフォルトの名無しさん
21/11/27 15:59:45.03 Xdw8IP3R.net
定義を示してほしいわな
F#界隈にもRust界隈にも無い用語だし

189:デフォルトの名無しさん
21/11/27 16:36:46.11 kX7QbhiL.net
何気なく使ってたけど調べてみたらC++用語だったか。しかも日本じゃ「フリー関数」という表記の方が一般的なんだな。
メンバー関数(メソッド)ではない素の関数ということで。

190:デフォルトの名無しさん
21/11/27 17:08:07.51 FtAU5QYE.net
その意味ならElixirは自由関数も部分適用も使えると思うが・・・

191:デフォルトの名無しさん
21/11/27 17:20:05.91 kX7QbhiL.net
そっちか。
Elixirのパイプラインの使用例でよく見る形式が部分適用とは違うんで使えないものと思っていた。すまん。
部分適用は別の表記になるんだな。

192:デフォルトの名無しさん
21/11/27 17:59:12.10 g2vJAoph.net
C++でもフリー関数と言われたら free() のこと思い浮かべそうだが

193:デフォルトの名無しさん
21/11/27 18:21:56.04 molZfSEM.net
>>178
そうは言っても現状の下のこれが直感的に分かり易いとは思えないけど、、LINQはSQLとは関係ないよ。
whereとかselectがそれに見えるけど、言語的には直行性を高めた統合クエリなだけ
let mut y: Vec<i32> = x.clone().filter(|p| p <= &5).collect();
y.sort_by_key(|t| -t);
let y: Vec<i32> = y.into_iter().map(|t| t * 2).collect();

194:デフォルトの名無しさん
21/11/27 19:30:03.08 tWlgYd9Y.net
>>189
どこが見にくいのか具体的に教えて
use itertools::Itertools;
let y: Vec<i32> = x
 .filter(|p| p <= &5)
 .sorted_by_key(|t| -t)
 .map(|t| t * 2)
 .collect();

195:デフォルトの名無しさん
21/11/27 21:12:33.33 VfaT4D+K.net
>>185
> 何気なく使ってたけど調べてみたらC++用語だったか
どこの世界に非メンバ関数をフリー関数という馬鹿がいるのか詳しく
CかC++の規格のどこを参照すれば定義されているのか詳しく

196:デフォルトの名無しさん
21/11/27 21:19:49.42 w2+KtZN6.net
江添の馬鹿が言ってた。
URLリンク(cpplover.blogspot.com)

197:デフォルトの名無しさん
21/11/27 21:31:03.67 w2+KtZN6.net
Herb Sutterという馬鹿も使ってるな。
URLリンク(www.open-std.org)

198:デフォルトの名無しさん
21/11/27 21:39:57.32 VfaT4D+K.net
規格の上ではまだ見つけられないが
URLリンク(timsong-cpp.github.io)
member function
non-member function
という当然の名称が出てきている
日本語版の規格分かる人「フリー関数」とやらを引用してくだしあ

199:デフォルトの名無しさん
21/11/27 21:43:56.78 w2+KtZN6.net
規格で定義された用語というより業界用語的なもんでないの
URLリンク(github.com)

200:デフォルトの名無しさん
21/11/27 21:44:30.32 lc2cVbH3.net
馬鹿っていちいち言うなよ
素直になれや

201:デフォルトの名無しさん
21/11/27 22:07:33.35 tWlgYd9Y.net
その「フリー関数」とはクラスのメンバー関数ではない非メンバー関数として
クラスのないRustではその非メンバー関数の定義はどうなるの?
例えば以下のprint_all()は適当に作ったトレイトPrintAllのメンバーかもしれないけど
現実には('a'..='z').print_all();が動作してしまうわけで『誰のメンバー関数』なの?それとも非メンバー関数?
trait PrintAll<T> {
 fn print_all(self);
}
impl<I: Iterator<Item=T>, T: Display> PrintAll<T> for I {
 fn print_all(self: I) {
  self.for_each(|x| println!("{}", x));
 }
}

202:デフォルトの名無しさん
21/11/27 22:20:27.30 w2+KtZN6.net
第一引数がselfである関数(メソッド)を自由関数として呼び出すことはできるけどその逆は真ではないってことじゃないかな。
URLリンク(en.wikipedia.org)

203:デフォルトの名無しさん
21/11/27 22:24:30.93 dpgg2nfE.net
メソッド呼び出しできない関数は「フリー関数」ってことでええんちゃう?
非メンバ関数って呼ぶほうが断然一般的だとは思うが

204:デフォルトの名無しさん
21/11/27 22:47:33.66 riEP2Tv6.net
>>197
selfがIteratorだからクラス志向だとprint_all()はIteratorクラスのメンバーかな
しかしそのPrintAllはIteratorを継承してないから難しい

205:デフォルトの名無しさん
21/11/27 23:15:00.42 udgmz45E.net
URLリンク(dev.to)
この手のPhantomDataとジェネリクス使って特定の条件満たした状態じゃないとbuildとかのメソッドが実装されないようにしたりしたビルダーパターンってここの人たちはどう思ってる?
説明だけ見るとめっちゃ良いやん!って思うけどいざ自分で書くとメリットに対して無駄に複雑&使う側としてもエラーが見にくいとかなんか微妙に感じちゃう

206:デフォルトの名無しさん
21/11/28 00:27:08.53 j8Nrs0jp.net
>>200
例えばこのように任意の実装が出来るからprint_all()はIteratorのメンバーではなくあくまでもPrintAllのメンバー
struct V<T>(Vec<T>);
impl<T: Display> PrintAll<T> for V<T> {
 fn print_all(self) {
  self.0.into_iter().for_each(|x| println!("{}", x));
 }
}

207:デフォルトの名無しさん
21/11/28 00:30:34.72 Fw4ypgsa.net
重要なのはフリー関数の定義じゃなくてパイプライン演算子の適用範囲だぞ

208:デフォルトの名無しさん
21/11/28 00:54:44.73 j8Nrs0jp.net
>>201
長くて斜め読みしかしていないがもっとわかりやすく示すとこういうことか
まず状態を示すダミーな型を作っておく
trait State {}
impl State for ToDo {}
impl State for Done {}
#[derive(Debug)]
struct ToDo;
#[derive(Debug)]
struct Done;
次にビルダーの構造体にダミーな型も収容する (サイズはゼロ)
type PD<T> = std::marker::PhantomData<T>;
#[derive(Debug)]
struct Builder<SetA: State, SetB: State> {
 a: i32,
 b: i32,
 _a: PD<SetA>,
 _b: PD<SetB>,
}
つまり変数aがセットされたか否かの状態をダミーな_aの型で示す
(つづく)

209:デフォルトの名無しさん
21/11/28 00:58:02.64 j8Nrs0jp.net
>>204の続き
初期値ToDoで開始してセットされたらDoneに変える
impl<SetA: State, SetB: State> Builder<SetA, SetB> {
 fn new() -> Builder<ToDo, ToDo> {
  Builder { a: 0, b: 0, _a: PD {}, _b: PD {}, }
 }
 fn set_a(self, a: i32) -> Builder<Done, SetB> {
  Builder { a, b: self.b, _a: PD {}, _b: PD {}, }
 }
 fn set_b(self, b: i32) -> Builder<SetA, Done> {
  Builder { a: self.a, b, _a: PD {}, _b: PD {}, }
 }
}
全部がDoneになった時だけ実行可能にしておく
impl Builder<Done, Done> {
 fn execute(&self) {
  println!("OK: {:?}", self);
 }
}
最初の呼び出しをわかりやすく用
fn new_builder() -> Builder<ToDo, ToDo> {
 Builder::<ToDo, ToDo>::new()
}
あとは両方がセットされると実行できる
fn main() {
 new_builder().set_a(123).set_b(456).execute();
}
片方でもセットを忘れるとコンパイル時にexecute()が解決できず失敗する
自分でこのコードを毎回間違えずに書くのは面倒なのでマクロ化されるなら採用

210:デフォルトの名無しさん
21/11/28 01:06:31.53 eXqoW6w6.net
またチラ裏コードの垂れ流し
いい加減やめてほしい

211:デフォルトの名無しさん
21/11/28 02:33:07.17 ZOlCZyFx.net
>>201
こういうのは手書きするのではなくて derive で良い感じに実装してほしい
あとrustdocの出力がごちゃつきそうなのが気になる

212:デフォルトの名無しさん
21/11/28 02:38:47.39 D4pWSHhU.net
自己満足コード見せられても困るよな

213:デフォルトの名無しさん
21/11/28 02:48:11.47 Fw4ypgsa.net
config部分が静的に決まってるならいいけど
UIやコマンドラインから動的にconfigしたい場合Builder traitを用意してtrait objectとして持ち回して
.execute()するためにdowncastする必要が……とかで二度手間になりそう

214:デフォルトの名無しさん
21/11/28 02:53:52.09 ghhRE59c.net
>>201のコードがいいと感じる感性が理解できないよ

215:デフォルトの名無しさん
21/11/28 10:39:31.01 XbegH2kB.net
>>201
難しい話をすると
ビルダはディレクタに対して抽象化されており
一個のディレクタが複数のビルダをケアできることを考えると
必須パラメータというのをビルダ実装ごとに準備するなら
ビルダというインタフェースがディレクタに対して実質破綻してると思う
でも
ビルダインタフェースが正しい呼び出し順を想定してたりするのをアリとするなら
必須パラメータも同じように勝手に想定しておいて
使う側にはドキュメントなりなんなりで勝手に指示だしとけば十分とも思う
そんで
呼び出し順や必須か否かに想定を置きたくない
呼び出し側に完全な自由度を与えたビルダインタフェースを提供したいなら
インタフェース Fooビルダ {Fooビルダ a(); Fooビルダ b();}
クラス 実際のビルダ implements Fooビルダ {
Foo(必須な何か x) {略} // コンストラクタで与えるとか
Fooビルダ 必須なc() {略} /* 実際のビルダ固有のメソッドとして与えて
new 実際のビルダ().必須なc().a() などと呼ぶか
Fooビルダ a() {略}
Fooビルダ b() {略}
Foo create() {略}
}
のようにして、ビルダインタフェース側だけはクリーンに守っておけばスッキリかも?
元のURLにあるように何が必須かをパラメータ化したいという欲求は解消してないのは認める

216:デフォルトの名無しさん
21/11/28 11:48:41.93 sDAG0wCq.net
インタフェースとかクラスとか意味不明すぎ

217:デフォルトの名無しさん
21/11/28 23:35:20.49 Fzo1fdIE.net
ここまで意味不明な文章書けるのって逆に凄いよ
このレベルは久々に見たわ

218:デフォルトの名無しさん
21/11/29 01:53:08.06 zo5XubVi.net
Javaコードの識別子の部分を日本語で書いて
GoFのオリジナルのBuilderパターンを説明しただけっぽい
なんでRustスレでそんな話をしたのかだけは完全に謎だが……

219:デフォルトの名無しさん
21/11/29 02:06:35.83 27e/xIh/.net
普通のBuilderであまり困ったことないからなあ
操作によって遷移していく状態があって、状態ごとに可能な操作が違う(呼び出せるメソッドが違う)とかなら意味あると思う(Socketのbind->accept->read/writeみたいな)
ただこういうものはもはやBuilderと呼ぶべきものではないと思う

220:デフォルトの名無しさん
21/11/29 09:45:31.17 3xWgo/Oc.net
それはStateパターンでしょ

221:デフォルトの名無しさん
21/11/29 15:25:28.77 aqqw7fQi.net
URLリンク(play.rust-lang.org)
sもmutにしてDerefMutもimplしてるのになんでgの方は通らないんでしょうか?

222:デフォルトの名無しさん
21/11/29 16:49:12.44 4MgUQE5v.net
>>217
もっと単純に let z: *mut i8 = *s; も通らないので
これはDerefMutの条件であるmutable contextを満たしてないのではないか
そしてもちろん let z: &mut i8 = *s; は通るし **s = 88; も通るからDerefMut自体は機能している

223:デフォルトの名無しさん
21/11/29 18:03:30.09 3r4jR24z.net
PR出てるけどどうなるかわからない
URLリンク(github.com)
現状は
let s = &mut *s;
g(*s);
するか
g(&mut **s);
するか

224:デフォルトの名無しさん
21/11/29 18:58:43.82 Y4F1AeLY.net
>>219
おお、そのものズバリが
あざます!

225:デフォルトの名無しさん
21/11/30 18:31:42.77 8WvE/rry.net
ifの閉じカッコにセミコロンが必要となる条件を教えてください
以下のプログラムはそれが足りないと指摘されてコンパイルエラーとなり
セミコロンを付けると通って動作するのですがどういう原理なのでしょうか?
fn main() {
 for line in BufReader::new(io::stdin()).lines() {
  let line = line.unwrap();
  if let [first, second, rest] = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>()[..] {
   println!("{}:{}:{}", first, second, rest);
  }
 }
}

226:デフォルトの名無しさん
21/11/30 18:58:54.86 ZW4IpnTF.net
戻り値?

227:デフォルトの名無しさん
21/11/30 20:27:35.13 s7fhQ2Tk.net
ブロック式最後の式の値は、ブロック式の値として返るので drop されるタイミングがブロックの末尾よりも後の箇所になるということかな
for のブロックは値を返さないけど、ブロック式と同じ扱いをされているっぽい
URLリンク(play.rust-lang.org)

228:デフォルトの名無しさん
21/11/30 21:12:32.45 8WvE/rry.net
>>223
>> ブロック式最後の式の値は、ブロック式の値として返るので
もちろんおっしゃる通りでその例でも>>221の例でもif式の値は明瞭に()ですね
>> drop されるタイミングがブロックの末尾よりも後の箇所になるということかな
ブロック式の値として返るのは()ですから変数lineのdropタイミングが後にはならないように思うのですがどうなのでしょう?

229:デフォルトの名無しさん
21/11/30 21:32:53.10 hx6pGpzB.net
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
↑エラーメッセージに理由書いてるよ

230:デフォルトの名無しさん
21/11/30 21:55:20.40 8WvE/rry.net
>>225
そのエラーメッセージでは理由になっていないのではないでしょうか?
例えば(for文を使わない)>>223の以下の部分を
if let [_first, _second, _rest] = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>()[..] {}
このように2行へ書き換えても同じくセミコロンを付けろエラーとなりますが
let x = line.splitn(3, ' ');
if let [_first, _second, _rest] = x.collect::<ArrayVec<_, 3>>()[..] {}
このように2行へ書き換えるとコンパイルが通ります
let x = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>();
if let [_first, _second, _rest] = x[..] {}
この差をどう見るのか教えていただけますでしょうか

231:デフォルトの名無しさん
21/11/30 22:02:05.25 s7fhQ2Tk.net
>>224
・lineの寿命はif-let式の寿命と一致する
・ブロックの最後の文の寿命はブロックを囲む文の寿命と一致する
という仕様になっていると思われる
型は関係なくてブロック内の最後の式か否かが重要

232:デフォルトの名無しさん
21/11/30 22:26:55.08 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:デフォルトの名無しさん
21/11/30 22:31:28.50 hx6pGpzB.net
>>226
>let x = line.splitn(3, ' ');
>if let [_first, _second, _rest] = x.collect::<ArrayVec<_, 3>>()[..] {}

234:デフォルトの名無しさん
21/11/30 22:35:06.87 hx6pGpzB.net
すまん、投稿ミス。
値を返したいときはセミコロンを追加するだけじゃだめだから
一旦変数で受けてからその変数をブロックの最後に書く

235:デフォルトの名無しさん
21/11/30 22:39:09.24 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:デフォルトの名無しさん
21/11/30 22:41:34.40 rIKeeiBO.net
なんでセミコロン付けると一時オブジェクトの寿命変わるんだって思ったけどそういえばC++にもそんな仕様あったな……
完全式じゃなくて戻り値に使うから破棄されないってことか

237:デフォルトの名無しさん
21/11/30 23:55:05.80 Y6JwF3m3.net
>>230
ブロックの最後で返す値は変数に入れなくても複雑な式でも大丈夫ですよ

238:デフォルトの名無しさん
21/12/01 12:41:12.28 KNT1MQhQ.net
なんでBufReadトレイトはあるのにBufWriteトレイトは無いんですか?

239:デフォルトの名無しさん
21/12/01 13:25:08.66 2cjkBPbo.net
>>231
詳しく知りたければまずはここ↓だけど
URLリンク(doc.rust-lang.org)
言語自体をいじりたいわけじゃなければ
あんまり深追いしても役に立たないよ

240:デフォルトの名無しさん
21/12/01 16:06:22.55 oI4zTDt2.net
>>234
BufReadはReadに対して追加の機能(行単位の読み込みなど)があるけど
Writeに対して追加すべき機能がないからBufWriteは存在しないのではないかと思われる

241:デフォルトの名無しさん
21/12/01 21:58:24.00 QwFnQ8Qa.net
flushしなけりゃ下のレイヤのどこかで勝手にバッファリングされることがほとんどだから用意する意味がないんだろな。

242:デフォルトの名無しさん
21/12/01 23:34:44.63 hYYowF9a.net
>>237
いやBufWriteトレイトが存在しないだけであってBufWriterはちゃんとある
そしてBufWriterがバッファリングする最後の要
誰かが勝手にバッファリングしてくれることはない
例えば何行もファイルに書き込む時にBufWriter使わずに各行毎にwriteしてたら遅くなる

243:デフォルトの名無しさん
21/12/03 14:04:46.92 xjf4hyRh.net
URLリンク(crates.io)
とか
URLリンク(crates.io)
みたいなの使ってる人おる?
これ使うくらいならLL使うとは思うが

244:デフォルトの名無しさん
21/12/03 14:45:17.46 RidNMi7I.net
REPL的にコードスニペットの実行確認するために使ったりはできるのかな
今はplaygroundで事足りているが

245:デフォルトの名無しさん
21/12/04 15:22:12.31 f29/w5s1.net
Read::read_to_end()に空のVecを渡した時に戻り値のusizeとVecのlen()が違う値になる事って有り得ますか?

246:デフォルトの名無しさん
21/12/04 23:32:14.41 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:デフォルトの名無しさん
21/12/05 23:43:02.39 +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:デフォルトの名無しさん
21/12/06 12:54:15.14 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:デフォルトの名無しさん
21/12/06 13:12:38.43 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:デフォルトの名無しさん
21/12/06 13:28:57.99 GjZweGXf.net
どれもこれも分かりやすいとは思えない

251:デフォルトの名無しさん
21/12/06 15:59:22.06 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:デフォルトの名無しさん
21/12/06 16:01:51.04 NQsvo9rr.net
最近知ったボクの大発見書いていい?
let a: Option<i32> = None;
これは
let a = None::<i32>;
と書ける
関数のパラメータとして渡そうとして
f(None)で怒られたとき
f(None::<i32>)として怒られない
しょうもないレス失礼いたしました

253:デフォルトの名無しさん
21/12/06 16:21:14.38 BduPW1Ae.net
>>248
曖昧性を確定させる::<型>の指定は色々なところで出てくるね
例えばcollect::<Vec<_>>()とか
ブロックやクロージャの返り値でOk::<(),std::io::Error>(())とか

254:デフォルトの名無しさん
21/12/06 16:35:36.71 McsJgKJD.net
>>247
itertoolsのcartesian_productがほぼそれ

255:デフォルトの名無しさん
21/12/06 17:07:16.47 +ZC47hZJ.net
iproduct!

256:デフォルトの名無しさん
21/12/06 17:09:45.91 Fu08U5Ef.net
>>248
型パラメータは Option のパラメータなので順当に考えれば Option::<i32>::None と書くべきだし実際にそれで通るんだけども、
歴史的経緯でバリアントにも付けられるようになってる。
短く書けるから習慣的にはバリアントに型を付けるほうが多いかな……?

257:デフォルトの名無しさん
21/12/06 17:31:38.25 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:デフォルトの名無しさん
21/12/06 20:06:32.13 NQsvo9rr.net
>>249
> Ok::<(),std::io::Error>(())とか
正直見たことなかったです
>>252
> 歴史的経緯でバリアントにも付けられるようになってる。
(´・∀・`)ヘー
そういうわけなんですね

259:デフォルトの名無しさん
21/12/06 21:47:08.33 BduPW1Ae.net
>>254
例えばlet x = spawn(async { ... });して裏で何か処理をやらせといた結果を
後でもしエラーが出ていたら進めちゃいけないタイミングでx.await?;で確認するわけだけど
spawnが返す型をxに律儀に記述するのは面倒なのでそこは略すとして
asyncブロック内で?とOk(())だけ書くとコンパイラが文句を言うので仕方なく記載

260:デフォルトの名無しさん
21/12/06 22:11:44.75 NQsvo9rr.net
なるほど勉強になりました

261:デフォルトの名無しさん
21/12/07 21:26:04.18 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:デフォルトの名無しさん
21/12/08 14:18:48.01 6NuoEm2L.net
ARM版のWindowsでRustのコードを書くのってめんどくさいな
生のWindowsで使用する場合、VisualStudioに付属するx86用のリンカーが非推奨警告を無視すれば使えたものの、次期バージョンからx64専用になってしまうっぽい
一方、仮想環境等+VSCodeでは、RustAnalyzer等が機能せず苦労する・・・・
持ち運び用にケチってMacを買わなかったのが大問題だった、なんかいい方法ないのかな?そもそもARM Windowsで動くリンカーってVisualStudio付属のものしかないのかな?
ケチったって言ってもよくよく考えてみると大して金が浮いてもないし、変なもん買っちまった

263:デフォルトの名無しさん
21/12/08 14:36:22.94 W5vI+s6z.net
>>258
i686ターゲットのバイナリをバイナリ変換で動かしてるってこと?
aarch64-windowsターゲットとARM用のリンカ使えばネイティブのARMバイナリできるんじゃないかと思うけど

264:デフォルトの名無しさん
21/12/08 20:15:10.58 pzF9gjPk.net
バイナリバイナリルルルルルー。

265:デフォルトの名無しさん
21/12/08 21:25:01.32 t4Pzut9P.net
rustはどんどん新しい機能が追加されていくのはいいけど、
後方互換性を気にして過去に追加された「間違った」機能を削除するという
思い切ったこともやって欲しいな
これまでの言語は後方互換性にとらわれて滅茶苦茶になってるから

266:デフォルトの名無しさん
21/12/08 21:29:04.83 ff6DaDGr.net
>>261
C++かな?

267:デフォルトの名無しさん
21/12/08 21:44:15.05 tBq4QMAR.net
>>261
editionでは物足りない?

268:デフォルトの名無しさん
21/12/08 21:50:49.56 t8qOOWvR.net
実際2021editionではレンジパターンの ... が削除されて ..= に一本化された

269:デフォルトの名無しさん
21/12/09 08:53:14.94 sqaPNXyj.net
>>258
今どきDocker使うのはデフォだから何の問題もない、因みにRustAnalyzerも使える
使えないのは、復数のプロジェクトが見える状態にしてるから
今どき復数ウィンドウ立ち上げても何の問題もない、ルートフォルダを固有にしたら解決
つまり、調査不足が原因

270:デフォルトの名無しさん
21/12/09 10:59:17.60 4q0mFQ+L.net
ARM は安物のイメージがある。
WSL2, Linux, Docker, VSCode とか使えるのかな?
Mac も、M1 に変わったから

271:デフォルトの名無しさん
21/12/09 11:10:00.09 XwSSuf4e.net
原理的には ARM �


272:フほうがインテル系 (もはや AMD 系と呼ぶべきか) よりも高速化できる可能性があるとは言われている。 今以上に回路を細かくするのは無理というところまできてしまっているのでアーキテクチャのほうで見直しが必要なんだが インテル系は互換性が足かせになってしまっていてあまり思い切ったことが出来ない。 現時点はインテル系向けにチューニングされたソフトウェア資産が多いから上手くいっているけど将来もそうとは限らない。



273:デフォルトの名無しさん
21/12/09 11:45:18.26 t4DQqTrM.net
>>267
スレチだけどその話の出展あったら教えてほしい

274:デフォルトの名無しさん
21/12/09 14:22:31.39 RSXecyhf.net
CISCRISCの話じゃなくてメモリモデルの話ならそうかなって思う
今のx64って実質中身RISCって聞いたことあるし
Rustで言うとx64では全部SeqCstとして扱われるみたいな話

275:デフォルトの名無しさん
21/12/09 17:42:03.96 VJ9QB09P.net
リソースの話だけなら命令デコーダーとか?
x86_64は拡張や互換性とか可変長命令だったりで無駄にトランジスタ消費するのが電力性能比的に足かせみたいな

276:デフォルトの名無しさん
21/12/09 20:39:08.00 0MvTGuxY.net
今どきのプロセッサだと分岐予測器やキャッシュが支配的でデコーダなんて誤差だと思う
あと可変長は命令側の帯域やキャッシュ効率が良くなるという面もあってRISC系でも採用してることが多い
結局両者とも長年の改善で似たようなとこに落ち着いてるわけで、ISAが違うからどうこうみたいな話は結構眉唾

277:デフォルトの名無しさん
21/12/11 19:08:58.23 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:デフォルトの名無しさん
21/12/11 19:10:55.89 ZSpAs+oG.net
namaeじゃなくてnameな
aが余計
この程度の英語のスペル書けないとかプログラミング向いていないしやめた方がいいよ

279:デフォルトの名無しさん
21/12/11 19:21:25.94 UNEoSQah.net
自演ボケか?

280:デフォルトの名無しさん
21/12/11 19:35:01.57 K+rsGRUk.net
>>272
そのままだとarg1が消費されてなくなるのに参照だけ残ることになるからエラー
Stringで受ければいいよ
let name: String = arg1.unwrap_or(DEFAULT_NAME.to_string());

281:デフォルトの名無しさん
21/12/11 20:19:05.99 XRkKLs6o.net
>>273
すげーな。してはいけないレビューの典型例じゃねーか。
すげーな

282:デフォルトの名無しさん
21/12/11 20:24:40.06 Z1L5tslT.net
いやネタでしょ

283:デフォルトの名無しさん
21/12/11 20:29:51.18 /anFx7me.net
>>275
これだとarg1がSomeの時もto_string()が呼び出されて無駄なヒープアロケーションが走るのでunwrap_or_elseにすべき

284:デフォルトの名無しさん
21/12/11 22:35:07.46 oic9EtmK.net
みなさんありがとうございます
Stringにする方法は無事にこれで動きました
let name: String = arg1.unwrap_or_else(|| DEFAULT_NAME.to_string());
元の質問>>272のように&strにする方法は無いのでしょうか?
もし可能ならばto_string()のヒープアロケーションを減らせるかなという質問です

285:デフォルトの名無しさん
21/12/11 22:59:59.99 yVS9OnV5.net
>>279
Cowかな
let name: Cow<str> = arg1.map_or(Cow::Borrowed(DEFAULT_NAME), |s| Cow::Owned(s));

286:デフォルトの名無しさん
21/12/11 23:20:49.43 yVS9OnV5.net
場合によってはこれでもいいのかな?
let name: &str = &arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str());

287:デフォルトの名無しさん
21/12/11 23:54:40.62 tYxQqCnY.net
>>281
それでもよいけど正解はシンプルなこれ
let name: &str = if let Some(ref arg1) = arg1 { arg1 } else { DEFAULT_NAME };
まずarg1を消費しないようにrefで受ける
2代目のarg1は&Stringなので自動的に&strへderefされる

288:デフォルトの名無しさん
21/12/12 02:10:02.51 h/Sb7JBW.net
1.40からas_derefっつうのがあるんだってさ
let name = arg1.as_deref().unwrap_or(DEFAULT_NAME);
でもコマンドライン引数の場合は消費しないメリットがほぼ無いのでCowのほうがいいかな

289:デフォルトの名無しさん
21/12/12 04:28:54.46 8d+idsXS.net
どの型で統一すべきかは
(1) その後に加工伸長などするならString (arg1をここで&strに統一するのは無駄)
(2) 参照するのみなら&str (DEFAULT_NAMEをここでto_stringするのは無駄)
(3) その後に判明する条件次第で両ケースありうるならCow (ただし常にCow利用はCowコストが無駄)
って感じ?

290:デフォルトの名無しさん
21/12/12 10:07:32.08 svMJrknn.net
おそらくその通りだけど、CLIツールの初回一回だけのアロケーションにそこまでこだわるのがそもそも無駄って気もする
ループ内とかでもなければ雑にString作っちゃっていいかもね

291:デフォルトの名無しさん
21/12/12 10:31:14.68 eE6Pv/WZ.net
んだ

292:デフォルトの名無しさん
21/12/12 10:46:59.45 8d+idsXS.net
>>285
今回のケースはそうだね
ただしヒープ割り当てをなるべく避ける様々な手法を把握しているか否かは色んな局面で効いてくるから
今回6通りも動くコード例が示されたことは多様に対応可能な柔軟性の良さかな
気にしなくても書けるし気にすれば効率を上げることができる点で

293:デフォルトの名無しさん
21/12/12 18:38:25.33 h/Sb7JBW.net
>>284
Cowと&strに揃える場合の一番の違いはライフタイム管理
Stringを&strにするとライフタイム管理がつきまとうから
すぐ使いきる場合以外はCowに比べてメンテナンスしにくいコードになる

294:デフォルトの名無しさん
21/12/12 18:59:43.58 3rjDzGgS.net
文字列についてはStringにするかCow<str>にするか迷うくらいならinternしちゃうのも手かと
どのライブラリが定番なのかよく知らないけど

295:デフォルトの名無しさん
21/12/12 19:49:57.76 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:デフォルトの名無しさん
21/12/13 21:23:25.03 zBnuOauJ.net
ken okabeのqiitaの記事がまた炎上してるよ
mod_poppoにボコボコにされてる

297:デフォルトの名無しさん
21/12/13 22:30:34.09 i33Tname.net
あれ、Qiitaには垢バンされて投稿できないんじゃなかった?

298:デフォルトの名無しさん
21/12/13 23:00:30.90 Yx06Lw1d.net
ググってもよくわからないのですが、どういった方なんですか?

299:デフォルトの名無しさん
21/12/13 23:30:17.26 IeJGNs4K.net
盛大な時間の無駄になるだけなので調べてはいけない

300:デフォルトの名無しさん
21/12/13 23:59:51.20 mqpFvLOG.net
>>291
poppoとかいうやつも多様な定義や多様な解釈が存在している中で不要なイチャモンばかりだな
さらに冒頭のこれも
> JavaScriptで演算子オーバーロードを実現しようとするのは筋が悪


301:い たまたま例としてJavaScriptを用いているだけなのにそれすら理解できていない okabeは使用言語と無関係に成り立つ話をしてるだろ > reduceは二項演算ではなく三項演算として捉えるべき これも些細なことであって例えばRustなら fold()は『入力列・初期値・演算関数』の三項演算だけど reduce()は『入力列・(初期値は入力列の先頭なので無指定)・演算関数』の二項演算 とはいえokabeの方もイテレータすら扱っていないからイマイチ



302:デフォルトの名無しさん
21/12/14 00:07:08.47 LYbWtya0.net
Rust関係ねーだろ
二度とその名前を口に出すな

303:デフォルトの名無しさん
21/12/14 10:41:11.49 QBQJlKEt.net
P2P方式の2D対戦ゲームを作りたいと考えています。
おすすめのゲームエンジンやライブラリはございますか?

304:デフォルトの名無しさん
21/12/14 11:46:02.04 mpAOsF0a.net
>>297
あくまでゲームを作ることが目的なんだったら普通にUnityとかでいいんじゃない?
どうしてもRust使いたいならサーバー側で使えばいい

305:デフォルトの名無しさん
21/12/14 12:45:44.37 QBQJlKEt.net
>>298
個人的にRustが好きなので技術向上のためにもRustで作りたいと考えています。
現在はAmethystとlibp2pを用いて開発しようと考えているのですが、如何せん知識が浅くこれで目的のものが作れるのか分かりません。
是非先人の知恵をお貸しください。
Rustでの開発にロミオとジュリエットの恋ほどの壁があるという場合は、大人しくC++かUnityで作成します・・・

306:デフォルトの名無しさん
21/12/14 13:10:49.68 +JRF3Q+g.net
そんだけの情報ではなんともいえん。
見通しが立たないものを試行錯誤で作る場合には
モジュールではなくレイヤで分割したほうがいいという考え方がある。
要するに機能不足でもバグだらけでもコードが整理されてなくてもいいからとにかく「動くもの」を作って
その上に足りないものをどんどん足していくという方法論だ。
よくわかってないなら小さいもので色々やってみて知識を積み重ねるべきで、
よくわからんまま目的に向かって邁進してもあんまり技術向上にはならんよ。

307:デフォルトの名無しさん
21/12/14 13:22:32.10 QBQJlKEt.net
>>300
ありがとうございます
色々試してみます

308:デフォルトの名無しさん
21/12/14 13:53:41.90 ZTFSAiNI.net
>>299
Amethystは開発中止になったから今からやるのは微妙かも
gamedev.rsに今アクティブなエンジンやゲームがスクショ付きで載ってるから
そこからイメージにあうものを探すといいかもしれない

309:デフォルトの名無しさん
21/12/14 15:30:19.02 QBQJlKEt.net
>>302
そうだったんですね・・・
時間は掛かるかもしれませんが、色んなものを試して自分に合う物を探すことにします

310:デフォルトの名無しさん
21/12/15 07:48:40.06 inpCEPk8.net
技術を高める目的なら windows-rs や wgpu-rs みたいな一段下から積み上げるのも楽しいよ。
ゲーム作る道のりは遠くなるけど、画面に三角形出したり、キーの入力受け付けたりするだけで達成感が出てくる。

311:デフォルトの名無しさん
21/12/17 12:43:03.76 jilrKB7M.net
URLリンク(forest-watch-impress-co-jp.cdn.ampproject.org)
エディタ自体はvscodeに勝つの難しそうだがGPUIとやらが定番GUIフレームワークにならないか期待

312:デフォルトの名無しさん
21/12/17 16:39:33.05 6JlgT7vi.net
既出だったらすいません
前から疑問だったのですが、出力におけるprint!マクロのような入力用マクロが標準ライブラリに用意されていない理由ってなんですか?

313:デフォルトの名無しさん
21/12/17 18:11:01.90 tWB5K5S1.net
>>297
1対多で、broadcast するチャットルームのバックエンドなら、
Ruby on Rails 6 のAction Cable(WebSocket)が基本
JavaScript は、React, Phaser とか
【Rails】(送信時のリロード無し!)Action CableでSlack風チャットアプリを作成、2019/12
URLリンク(www.youtube.com)

314:デフォルトの名無しさん
21/12/17 18:36:09.20 ePonqmC1.net
>>306
この辺読んで
URLリンク(github.com)
URLリンク(github.com)

315:デフォルトの名無しさん
21/12/17 23:52:56.58 6JlgT7vi.net
>>308
熟読させていただきました。
私としてはたった数十行のコードであること且つ他のほとんどの言語に存在しているものなのであっても良いのかなと思ったのですが、Rustの基本理念を考えると慎重になる理由も理解出来ました。
Rustの経験が浅い私目線ではあまり腑に落ちませんでしたが、皆さんはどう考えていますか?

316:デフォルトの名無しさん
21/12/18 15:05:52.37 JzdvFl4u.net
熟読はしてないけど、外部ライブラリで簡単に実現可能であるなら
直感的には、本体メンテナの苦労を増やすほど価値があると思えないし別にいらんかな
こういうIOとかCLIプロンプトらへんの機能ってどうしても好みが分かれるというか、
ユースケースによって必要な機能がかなり違ってきちゃうと思うし

317:デフォルトの名無しさん
21/12/18 20:46:47.80 w6oxugk6.net
C++のiostreamが失敗作だから慎重になるのもわかる笑

318:デフォルトの名無しさん
21/12/18 23:17:58.09 SfwydFh9.net
>>306
C言語でのprintf相当はあるのにscanf相当がstdにないのはなぜか?ですね
逆になぜprintf相当がRustの標準ライブラリにあるのか?を考えてみると
(1) 読み書きの非対称性
人間が読むためにプログラムが書くことはエラー表示を含めて利用必須かつ頻出
一方で人間が書いたものをプログラムが読むことはレア
ファイルや通信相手への読み書きは各プロトコル/各API/シリアライズ等で対象外
(2) コンパイラサポート
print!やformat!等は頻出するので効率面からコンパイラサポートが効率的
実際にそれらが利用しているformat_args!はコンパイラ内蔵マクロ
(3) 標準ライブラリ採用
外部ライブラリで実現可能なものは採用しないが基本
今回はコンパイラ内蔵マクロだから採用
つまり出力は頻度と効率化で採用がクリアされたけど
入力は外部ライブラリで十分かなと

319:デフォルトの名無しさん
21/12/19 02:25:28.05 KXG/wmTu.net
しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える

320:デフォルトの名無しさん
21/12/19 04:21:35.56 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:デフォルトの名無しさん
21/12/19 06:54:36.03 KXG/wmTu.net
>>314
ワンライナー大好きかよ

322:デフォルトの名無しさん
21/12/19 07:00:31.55 1R2jF/rb.net
>>315
マルチラインだと標準ライブラリだけでもわかりやすくなる?

323:デフォルトの名無しさん
21/12/19 08:28:47.39 KXG/wmTu.net
>>316
あいやごめん。proconioのところはどうあがいてもプロコン専用のproconioが一番見やすいよ。それ用に特化されたライブラリだし
俺が大好きかよって言ったのは
println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" });
の部分

324:デフォルトの名無しさん
21/12/19 09:08:15.26 1R2jF/rb.net
どの言語でも三項演算子(相当)はワンライナーで書くんじゃね?

325:デフォルトの名無しさん
21/12/19 09:36:51.21 Tv9xxy1h.net
見た目汚いなw

326:デフォルトの名無しさん
21/12/19 09:42:08.31 1R2jF/rb.net
これでいいかね?
println!("{}", if v.into_iter().any(|n| n & 1 == 0) {
 "Even"
} else {
 "Odd"
});

327:デフォルトの名無しさん
21/12/19 09:57:56.98 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:デフォルトの名無しさん
21/12/19 10:13:36.41 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:デフォルトの名無しさん
21/12/19 10:17:01.07 KXG/wmTu.net
>>322
proconio使うw
Rustで競プロするにはIOごときに専用ライブラリ使うことになってなんかなあって思うけど、そう思いながら使う

330:デフォルトの名無しさん
21/12/19 12:54:53.29 XhCh7cuL.net
>>315
ワンライナーやクロージャでまとめて書くと所有権やライフタイムの問題が出にくいんだよ
他の言語と違ってRustで適切に分割して読みやすく書くのは初心者には難しい

331:デフォルトの名無しさん
21/12/19 13:44:27.43 JD8Mu2Jr.net
わけわからんくてビビってたらよく見るとPythonスレじゃなかった

332:デフォルトの名無しさん
21/12/19 15:04:40.83 9UFbsF2U.net
rustfmt使うでしょ普通

333:デフォルトの名無しさん
21/12/19 21:36:12.89 1R2jF/rb.net
>>326
println全体が改行されてしまった
println!(
 "{}",
 if BufReader::new(stdin())
  .lines()
  .next()
  .unwrap()
  .unwrap()
  .split(' ')
  .any(|s| s.parse::<isize>().unwrap() & 1 == 0)
 {
  "Even"
 } else {
  "Odd"
 }
);
一方で分割するとこうなった
let cond = BufReader::new(stdin())
 .lines()
 .next()
 .unwrap()
 .unwrap()
 .split(' ')
 .any(|s| s.parse::<isize>().unwrap() & 1 == 0);
println!("{}", if cond { "Even" } else { "Odd" });
if式自体はワンライナーーで正解とrustfmtはおっしゃってる

334:デフォルトの名無しさん
21/12/19 21:50:26.03 gPlFWszB.net
ワンライナー云々はフォーマットの話ではないやろ

335:デフォルトの名無しさん
21/12/19 22:05:50.34 1R2jF/rb.net
例えば>>321がif式を5行に分割しているが
それもrustfmtにより1行に修正された
Rust標準ライブラリのソースでもワンライナー
bool.rs: if self { Some(t) } else { None }
result.rs: let n = if self.inner.is_some() { 1 } else { 0 };
time.rs: let prefix = if f.sign_plus() { "+" } else { "" };
>>328
では何の話かね?

336:デフォルトの名無しさん
21/12/19 22:37:44.04 D79ys1jH.net
構造と書式を区別できんのはヤバイで

337:デフォルトの名無しさん
21/12/19 23:10:30.41 ZhiL7Huf.net
心底どうでもいい。
保守性に貢献するどころかマイナスになるようなクソプライドコードの導入すんなよ。

338:デフォルトの名無しさん
21/12/19 23:14:48.39 4jRnwXL4.net
また性懲りもなくコードべたべた書いてんのか

339:デフォルトの名無しさん
21/12/19 23:21:45.51 cDs+Q4pL.net
rustfmtだから書式の話やで

340:デフォルトの名無しさん
21/12/19 23:25:17.24 /BRS7QS/.net
区別できなかったからrustfmtを持ち出したんやろ
どこに改行入れるべきかって話だと思ったんだろなww

341:デフォルトの名無しさん
21/12/19 23:41:46.15 1R2jF/rb.net
rustfmtを持ち出したのは俺じゃないぜ
あと今回のケースならここは分割するよな
let reader = BufReader::new(stdin());
let line = reader.lines().next().unwrap().unwrap();
let is_even = line.split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0);

342:デフォルトの名無しさん
21/12/19 23:48:52.91 m2ZvKw+8.net
汚コード

343:デフォルトの名無しさん
21/12/19 23:59:56.43 cDs+Q4pL.net
問題文が>>314でこうなってるから
>> | 入力は以下の形式で標準入力から数値が与えられる。
>> | a b c d e
if let [a, b, c, d, e] = line
 .splitn(5, ' ')
 .map(|s| s.parse::<isize>().unwrap())
 .collect::<ArrayVec<_, 5>>()[..] {
あとこれでいい
let is_even = a & b & c & d & e & 1 == 0;

344:デフォルトの名無しさん
21/12/20 05:23:59.31 XPDM+Al+.net
そういえばいつの間にか
let variable = 3;
println!("{variable}");
みたいな書き方が出来るんだけどこれ前からだっけ?

345:デフォルトの名無しさん
21/12/20 05:50:08.07 MpI5dMic.net
>>338
それはまだnightlyだけですよ
来月の1.58からstableになって使えるようになる予定

346:デフォルトの名無しさん
21/12/20 11:31:40.46 vxPhPqzv.net
>>335
構造化の基本を学びましょう

347:デフォルトの名無しさん
21/12/20 18:38:24.90 +mZvzmRI.net
どちらのコードも正解

348:デフォルトの名無しさん
21/12/20 18:57:17.41 rubGoZ9q.net
コードに「間違い」はあっても「正解」はない

349:デフォルトの名無しさん
21/12/20 19:04:29.92 MpI5dMic.net
間違っているコードは出ていないような
問題視してる人は具体的に何を問題にしているの?

350:デフォルトの名無しさん
21/12/20 20:55:59.37 lwZpjeWf.net
アスぺ思考はこれだから

351:デフォルトの名無しさん
21/12/21 11:25:19.41 TTfv6HaA.net
URLリンク(doc.rust-jp.rs)
ここの最後のところに
パターンと関わるマッチガードの優先度は、以下のように振る舞います:
(4 | 5 | 6) if y => ...
以下のようにではありません:
4 | 5 | (6 if y) => ...
とあるんですが、後者のようになってほしい場合は4|5と6 if yを別々に書くしか無いですか?

352:デフォルトの名無しさん
21/12/21 11:56:47.99 BV9oeByN.net
>>345
ガード構文がこう「『Pattern』 if 『Expression』」なのでそうなりますね

353:デフォルトの名無しさん
21/12/22 20:44:35.79 7pEHjDF/.net
sixtyfpsってどう?

354:デフォルトの名無しさん
21/12/22 22:58:00.27 mfli1g17.net
> しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える
いや、ほぼ公認のクレートなんだが・・・
謎の専用ライブラリとかいってる時点で、お察しか?
あと、見た目悪いってどういうことなんかね
includeしたら見た目悪すぎなわけ?

355:デフォルトの名無しさん
21/12/22 23:53:48.10 Wk3NOZd2.net
Rust bookの以下の記述について質問です
URLリンク(doc.rust-jp.rs)クロージャを返却する
> 以下のコードは、クロージャを直接返そうとしていますが、コンパイルできません:
>
> fn returns_closure() -> Fn(i32) -> i32 {
> |x| x + 1
> }
> コンパイラには、クロージャを格納するのに必要なスペースがどれくらいかわからないのです。
> この問題の解決策は先ほど見かけました。
>
> fn returns_closure() -> Box<Fn(i32) -> i32> {
> Box::new(|x| x + 1)
> }
とBox化しなさいと書かれているのですが
以下のようにimplを付けるとBoxを使わなくてもコンパイルが通り動きました
fn make_closure_add1() -> impl Fn(i32) -> i32 {
|x| x + 1
}
このimpl付加は暗に自動的にBox化されているということなのでしょうか?

356:デフォルトの名無しさん
21/12/23 00:23:38.98 p+r9sE2/.net
ここを読む
URLリンク(doc.rust-lang.org)

357:デフォルトの名無しさん
21/12/23 07:21:11.33 esNMmzKz.net
>>348
そりゃあcratesio に上がったものは空っぽでもゴミでも全部公認だわなw

358:デフォルトの名無しさん
21/12/23 15:17:54.33 BEeWZFks.net
>>342
逆だ、コードは常に「正解」で動いていて「間違い」ない。
あんたの書いたバグもコンピューターにとっては一部の隙もなく正解であり、書かれたその通りに動き、無慈悲である。
同じ目的で、多数、あるいは二人の人が書いたコードで違いが出るのは「表現の違い」であり「間違い」と決めつける
のは人間の主観や嗜好でしかなく、仮にコードへ正誤を求めるなら明確に表現できていなればならず、矛盾が生じる

359:デフォルトの名無しさん
21/12/23 15:32:21.87 GoKXBRn5.net
コンパイルが通らないコードも正解なのかい?

360:デフォルトの名無しさん
21/12/23 15:39:30.16 9VjYa60R.net
えらいポエミーやな

361:デフォルトの名無しさん
21/12/23 18:55:13.24 TD851Muu.net
”動いていて”と言っているからコンパイルは通ってる前提だろう、”コードへ正誤を求める”といっているから
仮にコンパイルが通らないコードは明確にそれ(誤り・間違い)が表現できている
ポエミーなのはその通りだろう

362:デフォルトの名無しさん
21/12/23 21:22:53.78 NwYcCv97.net
>>349
Boxとはヒープを使うということです
Rustではコードで明示的に指定しない限り勝手にヒープが使われることはないです
(もちろんBox以外にもVecやStringなどヒープを使うものを使ってもそれは明示的に指定したことになります)
その Box<Fn(i32) -> i32> は今は Box<dyn Fn(i32) -> i32> と書く必要があります
では本題の impl Fn(i32) -> i32 と書いた場合はどうなるのでしょうか?
以下のように3種類のクロージャを作ってサイズや型を表示させてみると
fn main() {
 let direct_closure = |x: i32| x + 1;
 let impl_closure = make_impl_closure();
 let box_closure = make_box_closure();
 println!("{} {}", std::mem::size_of_val(&direct_closure), type_of(&direct_closure));
 println!("{} {}", std::mem::size_of_val(&impl_closure), type_of(&impl_closure));
 println!("{} {}", std::mem::size_of_val(&box_closure), type_of(&box_closure));
}
fn make_impl_closure() -> impl Fn(i32) -> i32 {
 |x| x + 1
}
fn make_box_closure() -> Box<dyn Fn(i32) -> i32> {
 Box::new(|x| x + 1)
}
fn type_of<T>(_: &T) -> &'static str {
 std::any::type_name::<T>()
}
実行結果は以下のように表示されます
0 tmp::main::{{closure}}
0 tmp::make_impl_closure::{{closure}}
16 alloc::boxed::Box<dyn core::ops::function::Fn<(i32,)>+Output = i32>
つまりimplでは直接クロージャ指定したのと全く同じです
(上記では定義した関数名だけが異なる)

363:デフォルトの名無しさん
21/12/23 21:33:09.04 soQwByyI.net
今日はポエマー多いなw

364:デフォルトの名無しさん
21/12/23 22:34:57.88 NwYcCv97.net
では常に impl を使えばよいのかというと
以下のような条件によって異なるクロージャを返す時
ここで Box を使わず impl Fn(i32) -> i32 にしようとすると
2つのクロージャの型が違うとコンパイラに怒られます
fn make_closure(curry: Option<i32>) -> Box<dyn Fn(i32) -> i32> {
 if let Some(curry) = curry {
  Box::new(move |x| x + curry)
 } else {
  Box::new(|x| x + 1)
 }
}
結局クロージャでない場合と同じ話で
同じトレイトでも型が異なるものが同居する時にBox化します
>>349のRust bookの例はBox化が不要なケースでBox化だから混乱しますね

365:デフォルトの名無しさん
21/12/24 11:53:17.86 8qqh3vKr.net
コンパイル通って�


366:黷ホ全て正解とかバカ丸出し。 厳密な定義でも使えない定義があるってことすら理解してなさそう。



367:デフォルトの名無しさん
21/12/24 12:05:46.49 0hdsBqvb.net
型安全だったらコンパイル通れば実行時エラーにならないという点で全て正解っていうのは別に間違ってないと思うけど?
これにケチつけるのは流石にどうかと

368:デフォルトの名無しさん
21/12/24 12:44:01.96 2tHLRFeD.net
バカ丸出しにお前バカだろとわざわさ言うのもバカなんじゃなかろうか

369:デフォルトの名無しさん
21/12/24 15:42:15.21 8qqh3vKr.net
>>360
実行時エラーにならないなんて最低限のところだっつーの。だからバカだっていうんだよ。

370:デフォルトの名無しさん
21/12/24 16:05:46.66 GD01KKAb.net
もしかしてrustはlinuxに取り込まれるわけねーだろって言い張っていた人?
予言外していたよね。お疲れ様です。

371:デフォルトの名無しさん
21/12/24 16:08:19.93 7q1GmIfa.net
バカをスルーできないバカっているよねー
>>364
お前の事な

372:デフォルトの名無しさん
21/12/24 16:10:39.10 GD01KKAb.net
なんか草

373:デフォルトの名無しさん
21/12/24 16:20:12.59 GD01KKAb.net
25 デフォルトの名無しさん sage 2021/04/27(火) 08:00:23.09 ID:/+bIFNU8
>>23
あのね。。書けばそうなるってものじゃなくてそれを実装しなきゃならんのよ。。
コンパイラにそういったコンテクストを判断させるのがめちゃくちゃ難しいっていってるでしょ?
なんでそんなに読み取れないの?
27 デフォルトの名無しさん sage 2021/04/27(火) 16:10:45.63 ID:/+bIFNU8
>>26
だからそのコードじゃpanic捉えきれねーからカーネルに入れるわけねーだろって
言ってんじゃん。。何読んでんだよ。
28 デフォルトの名無しさん sage 2021/04/27(火) 18:23:48.67 ID:n/AWrch2
まあ半年後どうなるかで誰が正しかったかは分かるわな
29 デフォルトの名無しさん sage 2021/04/27(火) 20:32:29.92 ID:/+bIFNU8
半年も経たなくてももうわかってるっつーの。。だからちゃんと英語の勉強しましょうね。
完全に同一人物だよね

374:デフォルトの名無しさん
21/12/24 16:26:02.78 GD01KKAb.net
URLリンク(lkml.org)
英語読めんならこれになんて書かれているのかわかるよね?

375:デフォルトの名無しさん
21/12/24 16:31:02.04 GD01KKAb.net
予想が完全に外れたID:8qqh3vKrを晒し上げ♪♪♪
ここまで簡単な予想を外すとかバカ過ぎて生きていけなさそうwww
馬鹿丸出しですねwwwwww

376:デフォルトの名無しさん
21/12/24 16:40:31.03 8qqh3vKr.net
素でバカなんだな。。もうコンパイル通ったんで俺の仕事終わりとか現場で言ってろよ。。話にもならん。

377:デフォルトの名無しさん
21/12/24 16:42:14.31 /xk3NPni.net
>>362
最低限の性質を満たしている⇔正解って言ってんじゃん。。何読んでんだよ。
なんでそんなに読み取れないの?
だからバカだっていうんだよ。
だからちゃんと日本語の勉強しましょうね。

378:デフォルトの名無しさん
21/12/24 16:45:16.93 /xk3NPni.net
>>369
なお予言を外したことについては一貫してノータッチwwwww
話をしたくないのは君だよねwwwwww

379:デフォルトの名無しさん
21/12/24 16:46:19.44 /xk3NPni.net
>>369
同一人物だってことはバレバレだっつーの。バカ丸出し。wwwwwwwwww

380:デフォルトの名無しさん
21/12/24 17:12:05.04 jmk0MHfo.net
どうでもええわRustの話しろ

381:デフォルトの名無しさん
21/12/24 17:38:56.03 8qNIErj3.net
厳密な定義でも使えない定義?Rustに特定条件下でCのような未定義になる動作あったっけ?

382:デフォルトの名無しさん
21/12/24 18:41:11.93 759ZBatD.net
スレの文脈はしらんけど、
Rustではunsafeを使ってなければコンパイラが、未定義動作が起きないということや、データ競合がないことを保証をしてくれるよ

383:デフォルトの名無しさん
21/12/24 19:10:24.57 /xk3NPni.net
>>369
予言外れましたよね?wwwwwwww

384:デフォルトの名無しさん
21/12/25 15:28:33.08 lsYj53Mi.net
Rustでフロントエンドしてる奴おる?

385:デフォルトの名無しさん
21/12/26 12:56:45.57 NwCcamJz.net
Rustの勉強を昨日から開始した。後は構造体とかかな。

386:デフォルトの名無しさん
21/12/26 17:26:13.09 r


387:Nqv+UWs.net



388:デフォルトの名無しさん
21/12/26 19:27:36.42 IL2U4vJU.net
Rustはこう謳っている
>なぜRustか?
>パフォーマンス
>信頼性
>生産性
真っ向から反するコードを貼ってりゃゴミ・クソ言われて当然なんだよなぁ

389:デフォルトの名無しさん
21/12/26 19:29:23.79 Haex5ds9.net
すまんが、配列に入った数値の平均ってパッと出せないもんなの?
他言語でふにゃふにゃになった俺の頭でコードを書いたら、桁の溢れとか精度とか酷えことになりそう・・・・

390:デフォルトの名無しさん
21/12/26 20:24:04.94 s+fXV5dW.net
コードもゴミだったがそれ以上に考え方がゴミだったからな

391:デフォルトの名無しさん
21/12/26 20:42:21.32 M+F+5/6j.net
>>381
これ使ったらよいのでは
URLリンク(docs.rs)

392:デフォルトの名無しさん
21/12/26 22:30:25.75 L9HJqboW.net
>>381
普通に平均を求めるだけではダメなのでしょうか?
fn main() {
assert_eq!(5.5, (1..=10).average());
assert_eq!(6.8, [2.3, 8.7, 9.4].average());
}
use num::ToPrimitive;
trait Average {
fn average(self) -> f64;
}
impl<I> Average for I
where I: IntoIterator, <I as IntoIterator>::Item: ToPrimitive,
{
fn average(self: I) -> f64 {
self.into_iter().fold((0.0, 1.0), |(ave, size), n| (ave + (n.to_f64().unwrap() - ave) / size, size + 1.0)).0
}
}

393:デフォルトの名無しさん
21/12/27 00:09:24.17 wxukv015.net
カハンの加算アルゴリズムというのがある

394:デフォルトの名無しさん
21/12/27 09:11:03.63 9DXmjbrK.net
汚コードキタ━!

395:デフォルトの名無しさん
21/12/27 10:50:10.93 BFpPIAiX.net
何でもトレイト化するアホ

396:デフォルトの名無しさん
21/12/27 12:29:15.17 PxL7gTAR.net
ゴミをゴミだといって何が悪い!

397:デフォルトの名無しさん
21/12/27 12:32:52.22 OyINMfYQ.net
ここの人たちってplaygroundとかなんで完全に動かせるコードで提示しないんだろ・・・?
アドバイス貰うにも回答するにも一生懸命スペース全角置換したり、まじ両方キモイw
trait Averagewwwww

398:デフォルトの名無しさん
21/12/27 13:09:28.61 PX/mZ8bI.net
こう言う時って普通の関数にしちゃいかんの?

399:デフォルトの名無しさん
21/12/27 14:19:38.18 Btn3kp2t.net
普通の関数にすべきかどうかはメソッドチェーンにしたいかどうかで判断すればよろしい

400:デフォルトの名無しさん
21/12/27 14:43:10.42 0vghZEjd.net
>>389
playgroundでは自己顕示欲が満たせないんだよw
まあplaygroundでは動かせないコードもあるけどな

401:デフォルトの名無しさん
21/12/27 15:03:42.29 6JVZDUUj.net
>>381
こういう子は、移動平均出したくなった時とかどうすんだろ…
愚直に毎回平均出す関数とか使っちゃうわけ?

402:デフォルトの名無しさん
21/12/27 21:04:27.03 K3JIQJJi.net
しょうがない、一応は専門家が書いているであろう他言語の実装を参考にしよう・・・・
URLリンク(source.dot.net)
俺様、信頼して使っていたメソッドの衝撃の事実を知る

403:デフォルトの名無しさん
21/12/27 21:09:19.15 h+0xE8z4.net
浮動小数点型ならそういう素直な実装で十分だよ

404:デフォルトの名無しさん
21/12/27 21:53:06.04 N7w3YVE+.net
>>384
それだと桁溢れは防止できているが誤差蓄積の対処ができていない
もう一つパラメタを増やしてこうしたほうがいい
fn average(self: I) -> f64 {
self.into_iter().fold((0.0, 1.0, 0.0), |(ave, size, fix), n| {
let diff = (n.to_f64().unwrap() - ave) / size - fix;
let new_ave = ave + diff;
(new_ave, size + 1.0, (new_ave - ave) - diff)
}).0
}
>>387
イテレータメソッド化するにはそのためのtrait宣言が必須
もしわからないならitertoolsなどのイテレータ拡張ライブラリを見よう
>>389
標準ライブラリのsum()がtrait Sumを使っているからtrait Averageでもまあいいとは思う
ただし今回はイテレータメソッド拡張のみに用いているようだからtrait IteratorExtなどの命名がわかりやすいとは思う

405:デフォルトの名無しさん
21/12/27 21:56:50.25 20E7BwbM.net
IteratorExt大草原、まじに入院してほしいw

406:デフォルトの名無しさん
21/12/27 22:01:57.73 6/3kWl6D.net
イテレータメソッドにする必要ある?

407:デフォルトの名無しさん
21/12/27 22:15:24.91 N7w3YVE+.net
>>398
標準ライブラリにおいてsum()やproduct()
それを一般化したfold()やreduce()
さらにmax()やmin()など当然イテレータメソッドになっている
むしろ今回のaverage()だけをイテレータメソッドにしない理由が見当たらない

408:デフォルトの名無しさん
21/12/27 22:20:18.56 6/3kWl6D.net
>>399
じゃあなんで標準ライブラリにないの?

409:デフォルトの名無しさん
21/12/27 22:25:16.01 h+0xE8z4.net
カハンの加算使ったのか

410:デフォルトの名無しさん
21/12/27 22:31:56.63 /o/Y1bP3.net
>>400
入力型と出力型で大量の組み合わせ(例:i32→f32)が用途に応じて要求されるのと
単純に合計をサイズで割った平均でよい用途もあれば
件数が多いと合計がオーバーフローするからその対策が欲しい用途もあれば
桁が大きく異なるデータ列の場合に浮動小数点の誤差改善が欲しい用途など多岐にわたる
だから平均を標準ライブラリで何か一つ用意は無理

411:デフォルトの名無しさん
21/12/27 22:51:58.74 Btn3kp2t.net
単にこれまで標準ライブラリに入れようとした人がいなかったか
そういう人はいたが必要性を説得できなかっただけでしょう
sumやproductに比べるとユースケース限られるしね

412:デフォルトの名無しさん
21/12/27 23:21:10.48 iNGO9QKv.net
"ave"のせいで頭に入ってこない

413:デフォルトの名無しさん
21/12/28 00:10:56.21 THzUMFur.net
「件数が多いと合計がオーバーフローするからその対策が欲しい用途」そんな考えがオカシイ
sumですらオーバーフローに言及しているだけで対策が欲しいから、だからstdじゃないという理由では無い
URLリンク(doc.rust-lang.org)
When calling sum() and a primitive integer type is being returned, this method will panic if the computation overflows and debug assertions are enabled.
必要性を説得出来ないだけというのが正しい。浮動小数の加減算による誤差蓄積だって、浮動小数を扱うなら当然起こることだが
誤差改善が欲しい用途があるからstdじゃないとか嘘ばっかり言わないで?おまえさ、迷惑だからRust辞めてくれよ?
最小限、分かったふりで糞まき散らすな?

414:デフォルトの名無しさん
21/12/28 00:45:10.69 vzPVHyZI.net
>>405
それは君が無知
平均算出にはsumを求めずとも差分を逐次的に適用するアルゴリズムがあるoverflowを回避する対策で一般的に使われている
例えば>>383のstatsもその方法で平均を算出している
sumの例を出すのは見当違い

415:デフォルトの名無しさん
21/12/28 00:52:41.14 We8KhoPF.net
>>406
アルゴリズムの話じゃなくてstdに入ってない理由の説明がおかしいという指摘だと思うよ
言葉汚いし何言ってるかわかりづらいけど

416:デフォルトの名無しさん
21/12/28 01:20:29.34 vzPVHyZI.net
>>407
stdに入ってない理由?
一長一短ある複数のアルゴリズムがあるから外部でいいだろう

417:デフォルトの名無しさん
21/12/28 01:57:17.15 We8KhoPF.net
>>408
その理屈だとsortも該当するが
そもそも前提としてaverageをstd

418:デフォルトの名無しさん
21/12/28 02:00:22.76 We8KhoPF.net
>>409
途中で書き込んでしまった
そもそもaverageか類似の関数をstdに取り込む議論が過去にあったならそれをポイントしてほしい

419:デフォルトの名無しさん
21/12/28 02:37:31.31 vzPVHyZI.net
多数あり外部で十分派なのでそこは興味ない
sortは2種類しかなく2種類とも標準ライブラリでサポートしている

420:デフォルトの名無しさん
21/12/28 09:30:51.41 y5zg5Cpt.net
>>411
じゃ一番メジャーな外部ライブラリを教えてよ

421:デフォルトの名無しさん
21/12/28 10:24:44.25 ZpntEDp9.net
外部で十分と言えば、cratesは先着順で名前取れるからこの先優良ライブラリ程クソみたいな名前になっていくよね

422:デフォルトの名無しさん
21/12/28 10:41:12.74 zga8SsrA.net
>>413
マジでこれ
いい名前取るだけ取って何年も放置とか多すぎ
なんかいい方法無いかねぇ…

423:デフォルトの名無しさん
21/12/28 11:15:50.74 ZpntEDp9.net
ライブラリの永続性を保つのに名前でマッチさせるのやめてUUIDかハッシュか何かでマッチさせれば良かったのにみたいな気持ちはある

424:デフォルトの名無しさん
21/12/28 11:32:06.72 HJMjm+0C.net
>>414
横から失礼。
個人的にはそもそもcrate.io に頼るのがあまり好きでないなと。
Rust に限らない話だけど、こういった中央集権的なリポジトリを用意すること自体が名前争奪戦の元になるのではないかなと。
それぞれのWEBサイトで勝手に配布すればいいのにってね。
バージョン管理方法の方法論なんかも関わるから簡単な事ではないんだろうけど。

425:デフォルトの名無しさん
21/12/28 11:35:30.26 QBGkL4gv.net
現状でもGitHubから直接落としてくることも出来るけど、GotHubのリポジトリは消せてしまうからな

426:デフォルトの名無しさん
21/12/28 13:40:51.12 XD/wAJcN.net
cargo updateでマイナーバージョンアップやらせるのも規約決めたり工夫ご必要だし
専用のリポジトリ用意する方がわかりやすくはあるような
crates.io以外にも複数のリポジトリを混在して使えるようにできれば良いのかな

427:デフォルトの名無しさん
21/12/28 14:10:43.98 Qs/YVt0a.net
cargoはどこからでも落とせる
crates.ioなみに安全性、信頼性、永続性が確保できるんなら好きにすればいい

428:デフォルトの名無しさん
21/12/28 14:45:21.34 ZpntEDp9.net
永続性を謳うサービスで名前で管理したらそりゃあいい名前の取り合いになるよなあ

429:デフォルトの名無しさん
21/12/28 14:48:37.23 XD/wAJcN.net
>>419
ほんとだ、packageごとにregistry指定できるんだね
URLリンク(doc.rust-lang.org)

430:デフォルトの名無しさん
21/12/28 15:16:22.59 c9bIiubz.net
GoみたいにGithubがデファクトスタンダードなレジストリになっても一覧性の面で不便だし、crates.ioでいいと思うけどなあ

431:デフォルトの名無しさん
21/12/28 21:31:42.32 VUBOa1a1.net
セキュリティ監査付きのcrates.ioクローンが欲しい

432:デフォルトの名無しさん
21/12/28 21:33:45.43 m5VlhgmG.net
average()が気になってcratesだかcargoだか話逸らしに聞こえる

433:デフォルトの名無しさん
21/12/28 22:07:01.63 a7HoB6QX.net
ぼぼぼ、ぼくちんのために誰か優秀なaverage()をおながいします

434:デフォルトの名無しさん
21/12/28 22:22:38.58 ndrZKvgW.net
>>423
cargo auditでは足りない?

435:デフォルトの名無しさん
22/01/01 09:34:17.63 f7mn356m.net
>>411
「多数あり外部で十分派」なのに>>412には答えられないの??

436:デフォルトの名無しさん
22/01/01 19:34:25.31 u2SyaqDt.net
Why is my Rust build so slow?

437:デフォルトの名無しさん
22/01/01 20:01:31.38 YfLqYQwV.net
Because your PC is poor spec.

438:デフォルトの名無しさん
22/01/01 23:44:42.88 193tzZ58.net
URLリンク(fasterthanli.me)
この人の場合クソデカ型のせいでコンパイルが遅かったという話

439:デフォルトの名無しさん
22/01/02 10:42:43.84 adsjh4PJ.net
warpがクソみたいに重いって書いてるな

440:デフォルトの名無しさん
22/01/02 11:21:24.79 ulXuEZX0.net
sccacheとか入れてみるか

441:デフォルトの名無しさん
22/01/02 13:52:17.06 o9R7ffl7.net
当日お急ぎ便でSSDを買った

442:デフォルトの名無しさん
22/01/02 14:41:20.14 N3sGBcjr.net
>>432
bin crateのビルドに時間かかるなら sccache は効果薄いのでは

443:デフォルトの名無しさん
22/01/02 14:53:21.62 3FXnOBLq.net
高度IT人材、富士通は最大年収3500万円へ
「富士通年収3500万!」日本のIT企業の年収も、高額化してきました
AI人材の獲得に超本気 NECが新人事制度を9人に適用、富士通は最大年収3500万円へ
【年収3500万円も】富士通、「ジョブ型」人事制度を導入 幹部社員から 高度IT人材
来年度から副業解禁 人材多様化へ―大同生命次期社長
第一生命HD、副業解禁 約1万5000人対象
第一生命HD、副業解禁 1万5000人対象―大手生保初
IHI、国内8000人の副業解禁 重厚長大企業も転機
IHI、社外兼業を解禁 社内副業もルール化

444:デフォルトの名無しさん
22/01/02 21:56:13.39 Uu3cvt4h.net
効率を求め過ぎてモノリシックになりすぎると様々なコストが上昇してしまう
そこで分割
さらに内部もcrate分割で並行コンパイル

445:デフォルトの名無しさん
22/01/04 02:27:09.98 L+p8nbVX.net
Rustでノードが追加されたり消されたりする双方向グラフ扱いたくなったらどうするんだろ
Arenaじゃ追加削除してるうちにゴミがメモリ圧迫していくし

446:デフォルトの名無しさん
22/01/04 09:43:25.00 aGnbM+4r.net
>>437
Cursor使う
Arenaの場合はfree list用意して削除済み要素を再利用すればよい
Arenaが埋まったらreallocするのではなく同じサイズの新たなArenaを獲得していくようにすれば
不要になったArenaから解放できるからmalloc使う場合と同等のメモリ使用量に抑えられるかと
これでも不足するなら copy GC 的に compaction するしかなさそう

447:デフォルトの名無しさん
22/01/04 18:15:54.62 L+p8nbVX.net
>>438
なるほど…… 結構ガッツリ実装しなきゃいけなそうね。ありがとう。最後はGCを実装することになりそうなので、それならいい感じのGCを残しておいてくれたら良かったのにって気になるな

448:デフォルトの名無しさん
22/01/04 18:22:33.23 L+p8nbVX.net
Cursorってなんでしょう?

449:デフォルトの名無しさん
22/01/04 19:44:07.16 aGnbM+4r.net
>>440
これのこと (まだunatable)
URLリンク(doc.rust-lang.org)

450:デフォルトの名無しさん
22/01/04 20:59:48.62 /2oFrrnl.net
>>439
GCを必要とする用途は非常にレア
だから標準ライブラリには不要だが外部ライブラリに色々あるので大丈夫

451:デフォルトの名無しさん
22/01/04 22:15:51.15 aGnbM+4r.net
>>442
GCのライブラリ使ったことある?実用的だった?


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch