Rust part13

■ このスレッドは過去ログ倉庫に格納されています
2021/11/07(日) 10:04:59.35ID:pJhT3MIE
公式
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/
273デフォルトの名無しさん
垢版 |
2021/12/11(土) 19:10:55.89ID:ZSpAs+oG
namaeじゃなくてnameな
aが余計
この程度の英語のスペル書けないとかプログラミング向いていないしやめた方がいいよ
2021/12/11(土) 19:21:25.94ID:UNEoSQah
自演ボケか?
2021/12/11(土) 19:35:01.57ID:K+rsGRUk
>>272
そのままだとarg1が消費されてなくなるのに参照だけ残ることになるからエラー
Stringで受ければいいよ
let name: String = arg1.unwrap_or(DEFAULT_NAME.to_string());
2021/12/11(土) 20:19:05.99ID:XRkKLs6o
>>273
すげーな。してはいけないレビューの典型例じゃねーか。
すげーな
2021/12/11(土) 20:24:40.06ID:Z1L5tslT
いやネタでしょ
2021/12/11(土) 20:29:51.18ID:/anFx7me
>>275
これだとarg1がSomeの時もto_string()が呼び出されて無駄なヒープアロケーションが走るのでunwrap_or_elseにすべき
2021/12/11(土) 22:35:07.46ID:oic9EtmK
みなさんありがとうございます
Stringにする方法は無事にこれで動きました
let name: String = arg1.unwrap_or_else(|| DEFAULT_NAME.to_string());
元の質問>>272のように&strにする方法は無いのでしょうか?
もし可能ならばto_string()のヒープアロケーションを減らせるかなという質問です
2021/12/11(土) 22:59:59.99ID:yVS9OnV5
>>279
Cowかな
let name: Cow<str> = arg1.map_or(Cow::Borrowed(DEFAULT_NAME), |s| Cow::Owned(s));
2021/12/11(土) 23:20:49.43ID:yVS9OnV5
場合によってはこれでもいいのかな?
let name: &str = &arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str());
2021/12/11(土) 23:54:40.62ID:tYxQqCnY
>>281
それでもよいけど正解はシンプルなこれ
let name: &str = if let Some(ref arg1) = arg1 { arg1 } else { DEFAULT_NAME };
まずarg1を消費しないようにrefで受ける
2代目のarg1は&Stringなので自動的に&strへderefされる
2021/12/12(日) 02:10:02.51ID:h/Sb7JBW
1.40からas_derefっつうのがあるんだってさ
let name = arg1.as_deref().unwrap_or(DEFAULT_NAME);

でもコマンドライン引数の場合は消費しないメリットがほぼ無いのでCowのほうがいいかな
2021/12/12(日) 04:28:54.46ID:8d+idsXS
どの型で統一すべきかは
(1) その後に加工伸長などするならString (arg1をここで&strに統一するのは無駄)
(2) 参照するのみなら&str (DEFAULT_NAMEをここでto_stringするのは無駄)
(3) その後に判明する条件次第で両ケースありうるならCow (ただし常にCow利用はCowコストが無駄)
って感じ?
2021/12/12(日) 10:07:32.08ID:svMJrknn
おそらくその通りだけど、CLIツールの初回一回だけのアロケーションにそこまでこだわるのがそもそも無駄って気もする
ループ内とかでもなければ雑にString作っちゃっていいかもね
2021/12/12(日) 10:31:14.68ID:eE6Pv/WZ
んだ
2021/12/12(日) 10:46:59.45ID:8d+idsXS
>>285
今回のケースはそうだね
ただしヒープ割り当てをなるべく避ける様々な手法を把握しているか否かは色んな局面で効いてくるから
今回6通りも動くコード例が示されたことは多様に対応可能な柔軟性の良さかな
気にしなくても書けるし気にすれば効率を上げることができる点で
2021/12/12(日) 18:38:25.33ID:h/Sb7JBW
>>284
Cowと&strに揃える場合の一番の違いはライフタイム管理
Stringを&strにするとライフタイム管理がつきまとうから
すぐ使いきる場合以外はCowに比べてメンテナンスしにくいコードになる
2021/12/12(日) 18:59:43.58ID:3rjDzGgS
文字列についてはStringにするかCow<str>にするか迷うくらいならinternしちゃうのも手かと
どのライブラリが定番なのかよく知らないけど
2021/12/12(日) 19:49:57.76ID:be4Z/veb
>>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);
291デフォルトの名無しさん
垢版 |
2021/12/13(月) 21:23:25.03ID:zBnuOauJ
ken okabeのqiitaの記事がまた炎上してるよ
mod_poppoにボコボコにされてる
2021/12/13(月) 22:30:34.09ID:i33Tname
あれ、Qiitaには垢バンされて投稿できないんじゃなかった?
293デフォルトの名無しさん
垢版 |
2021/12/13(月) 23:00:30.90ID:Yx06Lw1d
ググってもよくわからないのですが、どういった方なんですか?
2021/12/13(月) 23:30:17.26ID:IeJGNs4K
盛大な時間の無駄になるだけなので調べてはいけない
2021/12/13(月) 23:59:51.20ID:mqpFvLOG
>>291
poppoとかいうやつも多様な定義や多様な解釈が存在している中で不要なイチャモンばかりだな
さらに冒頭のこれも

> JavaScriptで演算子オーバーロードを実現しようとするのは筋が悪い

たまたま例としてJavaScriptを用いているだけなのにそれすら理解できていない
okabeは使用言語と無関係に成り立つ話をしてるだろ

> reduceは二項演算ではなく三項演算として捉えるべき

これも些細なことであって例えばRustなら
fold()は『入力列・初期値・演算関数』の三項演算だけど
reduce()は『入力列・(初期値は入力列の先頭なので無指定)・演算関数』の二項演算

とはいえokabeの方もイテレータすら扱っていないからイマイチ
2021/12/14(火) 00:07:08.47ID:LYbWtya0
Rust関係ねーだろ
二度とその名前を口に出すな
297デフォルトの名無しさん
垢版 |
2021/12/14(火) 10:41:11.49ID:QBQJlKEt
P2P方式の2D対戦ゲームを作りたいと考えています。
おすすめのゲームエンジンやライブラリはございますか?
2021/12/14(火) 11:46:02.04ID:mpAOsF0a
>>297
あくまでゲームを作ることが目的なんだったら普通にUnityとかでいいんじゃない?
どうしてもRust使いたいならサーバー側で使えばいい
299デフォルトの名無しさん
垢版 |
2021/12/14(火) 12:45:44.37ID:QBQJlKEt
>>298
個人的にRustが好きなので技術向上のためにもRustで作りたいと考えています。
現在はAmethystとlibp2pを用いて開発しようと考えているのですが、如何せん知識が浅くこれで目的のものが作れるのか分かりません。
是非先人の知恵をお貸しください。
Rustでの開発にロミオとジュリエットの恋ほどの壁があるという場合は、大人しくC++かUnityで作成します・・・
2021/12/14(火) 13:10:49.68ID:+JRF3Q+g
そんだけの情報ではなんともいえん。

見通しが立たないものを試行錯誤で作る場合には
モジュールではなくレイヤで分割したほうがいいという考え方がある。
要するに機能不足でもバグだらけでもコードが整理されてなくてもいいからとにかく「動くもの」を作って
その上に足りないものをどんどん足していくという方法論だ。

よくわかってないなら小さいもので色々やってみて知識を積み重ねるべきで、
よくわからんまま目的に向かって邁進してもあんまり技術向上にはならんよ。
301デフォルトの名無しさん
垢版 |
2021/12/14(火) 13:22:32.10ID:QBQJlKEt
>>300
ありがとうございます
色々試してみます
2021/12/14(火) 13:53:41.90ID:ZTFSAiNI
>>299
Amethystは開発中止になったから今からやるのは微妙かも
gamedev.rsに今アクティブなエンジンやゲームがスクショ付きで載ってるから
そこからイメージにあうものを探すといいかもしれない
303デフォルトの名無しさん
垢版 |
2021/12/14(火) 15:30:19.02ID:QBQJlKEt
>>302
そうだったんですね・・・
時間は掛かるかもしれませんが、色んなものを試して自分に合う物を探すことにします
2021/12/15(水) 07:48:40.06ID:inpCEPk8
技術を高める目的なら windows-rs や wgpu-rs みたいな一段下から積み上げるのも楽しいよ。

ゲーム作る道のりは遠くなるけど、画面に三角形出したり、キーの入力受け付けたりするだけで達成感が出てくる。
2021/12/17(金) 12:43:03.76ID:jilrKB7M
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フレームワークにならないか期待
306デフォルトの名無しさん
垢版 |
2021/12/17(金) 16:39:33.05ID:6JlgT7vi
既出だったらすいません
前から疑問だったのですが、出力におけるprint!マクロのような入力用マクロが標準ライブラリに用意されていない理由ってなんですか?
2021/12/17(金) 18:11:01.90ID:tWB5K5S1
>>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
2021/12/17(金) 18:36:09.20ID:ePonqmC1
>>306
この辺読んで
https://github.com/rust-lang/rust/pull/75435
https://github.com/rust-lang/rfcs/pull/3196
309デフォルトの名無しさん
垢版 |
2021/12/17(金) 23:52:56.58ID:6JlgT7vi
>>308
熟読させていただきました。
私としてはたった数十行のコードであること且つ他のほとんどの言語に存在しているものなのであっても良いのかなと思ったのですが、Rustの基本理念を考えると慎重になる理由も理解出来ました。
Rustの経験が浅い私目線ではあまり腑に落ちませんでしたが、皆さんはどう考えていますか?
2021/12/18(土) 15:05:52.37ID:JzdvFl4u
熟読はしてないけど、外部ライブラリで簡単に実現可能であるなら
直感的には、本体メンテナの苦労を増やすほど価値があると思えないし別にいらんかな

こういうIOとかCLIプロンプトらへんの機能ってどうしても好みが分かれるというか、
ユースケースによって必要な機能がかなり違ってきちゃうと思うし
2021/12/18(土) 20:46:47.80ID:w6oxugk6
C++のiostreamが失敗作だから慎重になるのもわかる笑
2021/12/18(土) 23:17:58.09ID:SfwydFh9
>>306
C言語でのprintf相当はあるのにscanf相当がstdにないのはなぜか?ですね
逆になぜprintf相当がRustの標準ライブラリにあるのか?を考えてみると

(1) 読み書きの非対称性
人間が読むためにプログラムが書くことはエラー表示を含めて利用必須かつ頻出
一方で人間が書いたものをプログラムが読むことはレア
ファイルや通信相手への読み書きは各プロトコル/各API/シリアライズ等で対象外

(2) コンパイラサポート
print!やformat!等は頻出するので効率面からコンパイラサポートが効率的
実際にそれらが利用しているformat_args!はコンパイラ内蔵マクロ

(3) 標準ライブラリ採用
外部ライブラリで実現可能なものは採用しないが基本
今回はコンパイラ内蔵マクロだから採用

つまり出力は頻度と効率化で採用がクリアされたけど
入力は外部ライブラリで十分かなと
2021/12/19(日) 02:25:28.05ID:KXG/wmTu
しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える
2021/12/19(日) 04:21:35.56ID:1R2jF/rb
競プロ全然知らないけど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" });
2021/12/19(日) 06:54:36.03ID:KXG/wmTu
>>314
ワンライナー大好きかよ
2021/12/19(日) 07:00:31.55ID:1R2jF/rb
>>315
マルチラインだと標準ライブラリだけでもわかりやすくなる?
2021/12/19(日) 08:28:47.39ID:KXG/wmTu
>>316
あいやごめん。proconioのところはどうあがいてもプロコン専用のproconioが一番見やすいよ。それ用に特化されたライブラリだし
俺が大好きかよって言ったのは
println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" });
の部分
2021/12/19(日) 09:08:15.26ID:1R2jF/rb
どの言語でも三項演算子(相当)はワンライナーで書くんじゃね?
2021/12/19(日) 09:36:51.21ID:Tv9xxy1h
見た目汚いなw
2021/12/19(日) 09:42:08.31ID:1R2jF/rb
これでいいかね?
println!("{}", if v.into_iter().any(|n| n & 1 == 0) {
 "Even"
} else {
 "Odd"
});
321デフォルトの名無しさん
垢版 |
2021/12/19(日) 09:57:56.98ID:KXG/wmTu
俺ならこんな感じかなあ
俺は頭悪いから、途中結果に一つ一つ名前つけないとわかんなくなっちゃうわ
まあワンライナー見た時に「グエー」って思っただけだからごめん。「大好きかよ」とかいっておいてなんだけどあんま気にしないで

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);
}
2021/12/19(日) 10:13:36.41ID:1R2jF/rb
>>321
なるほど
じゃあ最初の標準ライブラリのみはどのように分けるのかな
println!("{}", if BufReader::new(stdin()).lines().next().unwrap().unwrap().split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0) { "Even" } else { "Odd" });
2021/12/19(日) 10:17:01.07ID:KXG/wmTu
>>322
proconio使うw
Rustで競プロするにはIOごときに専用ライブラリ使うことになってなんかなあって思うけど、そう思いながら使う
2021/12/19(日) 12:54:53.29ID:XhCh7cuL
>>315
ワンライナーやクロージャでまとめて書くと所有権やライフタイムの問題が出にくいんだよ
他の言語と違ってRustで適切に分割して読みやすく書くのは初心者には難しい
2021/12/19(日) 13:44:27.43ID:JD8Mu2Jr
わけわからんくてビビってたらよく見るとPythonスレじゃなかった
2021/12/19(日) 15:04:40.83ID:9UFbsF2U
rustfmt使うでしょ普通
2021/12/19(日) 21:36:12.89ID:1R2jF/rb
>>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はおっしゃってる
2021/12/19(日) 21:50:26.03ID:gPlFWszB
ワンライナー云々はフォーマットの話ではないやろ
2021/12/19(日) 22:05:50.34ID:1R2jF/rb
例えば>>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
では何の話かね?
2021/12/19(日) 22:37:44.04ID:D79ys1jH
構造と書式を区別できんのはヤバイで
2021/12/19(日) 23:10:30.41ID:ZhiL7Huf
心底どうでもいい。
保守性に貢献するどころかマイナスになるようなクソプライドコードの導入すんなよ。
2021/12/19(日) 23:14:48.39ID:4jRnwXL4
また性懲りもなくコードべたべた書いてんのか
2021/12/19(日) 23:21:45.51ID:cDs+Q4pL
rustfmtだから書式の話やで
2021/12/19(日) 23:25:17.24ID:/BRS7QS/
区別できなかったからrustfmtを持ち出したんやろ
どこに改行入れるべきかって話だと思ったんだろなww
2021/12/19(日) 23:41:46.15ID:1R2jF/rb
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);
2021/12/19(日) 23:48:52.91ID:m2ZvKw+8
汚コード
2021/12/19(日) 23:59:56.43ID:cDs+Q4pL
問題文が>>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;
2021/12/20(月) 05:23:59.31ID:XPDM+Al+
そういえばいつの間にか
let variable = 3;
println!("{variable}");
みたいな書き方が出来るんだけどこれ前からだっけ?
2021/12/20(月) 05:50:08.07ID:MpI5dMic
>>338
それはまだnightlyだけですよ
来月の1.58からstableになって使えるようになる予定
2021/12/20(月) 11:31:40.46ID:vxPhPqzv
>>335
構造化の基本を学びましょう
2021/12/20(月) 18:38:24.90ID:+mZvzmRI
どちらのコードも正解
2021/12/20(月) 18:57:17.41ID:rubGoZ9q
コードに「間違い」はあっても「正解」はない
2021/12/20(月) 19:04:29.92ID:MpI5dMic
間違っているコードは出ていないような
問題視してる人は具体的に何を問題にしているの?
2021/12/20(月) 20:55:59.37ID:lwZpjeWf
アスぺ思考はこれだから
2021/12/21(火) 11:25:19.41ID:TTfv6HaA
https://doc.rust-jp.rs/book-ja/ch18-03-pattern-syntax.html#%E3%83%9E%E3%83%83%E3%83%81%E3%82%AC%E3%83%BC%E3%83%89%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%AE%E6%9D%A1%E4%BB%B6%E5%BC%8F
ここの最後のところに

パターンと関わるマッチガードの優先度は、以下のように振る舞います:
(4 | 5 | 6) if y => ...
以下のようにではありません:
4 | 5 | (6 if y) => ...

とあるんですが、後者のようになってほしい場合は4|5と6 if yを別々に書くしか無いですか?
2021/12/21(火) 11:56:47.99ID:BV9oeByN
>>345
ガード構文がこう「『Pattern』 if 『Expression』」なのでそうなりますね
2021/12/22(水) 20:44:35.79ID:7pEHjDF/
sixtyfpsってどう?
2021/12/22(水) 22:58:00.27ID:mfli1g17
> しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える
いや、ほぼ公認のクレートなんだが・・・
謎の専用ライブラリとかいってる時点で、お察しか?

あと、見た目悪いってどういうことなんかね
includeしたら見た目悪すぎなわけ?
349デフォルトの名無しさん
垢版 |
2021/12/22(水) 23:53:48.10ID:Wk3NOZd2
Rust bookの以下の記述について質問です

https://doc.rust-jp.rs/book-ja/ch19-05-advanced-functions-and-closures.html#クロージャを返却する
> 以下のコードは、クロージャを直接返そうとしていますが、コンパイルできません:
>
> 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化されているということなのでしょうか?
2021/12/23(木) 00:23:38.98ID:p+r9sE2/
ここを読む
https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html#returning-closures
2021/12/23(木) 07:21:11.33ID:esNMmzKz
>>348
そりゃあcratesio に上がったものは空っぽでもゴミでも全部公認だわなw
2021/12/23(木) 15:17:54.33ID:BEeWZFks
>>342
逆だ、コードは常に「正解」で動いていて「間違い」ない。

あんたの書いたバグもコンピューターにとっては一部の隙もなく正解であり、書かれたその通りに動き、無慈悲である。
同じ目的で、多数、あるいは二人の人が書いたコードで違いが出るのは「表現の違い」であり「間違い」と決めつける
のは人間の主観や嗜好でしかなく、仮にコードへ正誤を求めるなら明確に表現できていなればならず、矛盾が生じる
2021/12/23(木) 15:32:21.87ID:GoKXBRn5
コンパイルが通らないコードも正解なのかい?
2021/12/23(木) 15:39:30.16ID:9VjYa60R
えらいポエミーやな
2021/12/23(木) 18:55:13.24ID:TD851Muu
”動いていて”と言っているからコンパイルは通ってる前提だろう、”コードへ正誤を求める”といっているから
仮にコンパイルが通らないコードは明確にそれ(誤り・間違い)が表現できている
ポエミーなのはその通りだろう
2021/12/23(木) 21:22:53.78ID:NwYcCv97
>>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では直接クロージャ指定したのと全く同じです
(上記では定義した関数名だけが異なる)
2021/12/23(木) 21:33:09.04ID:soQwByyI
今日はポエマー多いなw
2021/12/23(木) 22:34:57.88ID:NwYcCv97
では常に 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化だから混乱しますね
2021/12/24(金) 11:53:17.86ID:8qqh3vKr
コンパイル通ってれば全て正解とかバカ丸出し。
厳密な定義でも使えない定義があるってことすら理解してなさそう。
360デフォルトの名無しさん
垢版 |
2021/12/24(金) 12:05:46.49ID:0hdsBqvb
型安全だったらコンパイル通れば実行時エラーにならないという点で全て正解っていうのは別に間違ってないと思うけど?
これにケチつけるのは流石にどうかと
2021/12/24(金) 12:44:01.96ID:2tHLRFeD
バカ丸出しにお前バカだろとわざわさ言うのもバカなんじゃなかろうか
2021/12/24(金) 15:42:15.21ID:8qqh3vKr
>>360
実行時エラーにならないなんて最低限のところだっつーの。だからバカだっていうんだよ。
363デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:05:46.66ID:GD01KKAb
もしかしてrustはlinuxに取り込まれるわけねーだろって言い張っていた人?
予言外していたよね。お疲れ様です。
2021/12/24(金) 16:08:19.93ID:7q1GmIfa
バカをスルーできないバカっているよねー

>>364
お前の事な
365デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:10:39.10ID:GD01KKAb
なんか草
366デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:20:12.59ID:GD01KKAb
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
半年も経たなくてももうわかってるっつーの。。だからちゃんと英語の勉強しましょうね。

完全に同一人物だよね
367デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:26:02.78ID:GD01KKAb
https://lkml.org/lkml/2021/12/6/461

英語読めんならこれになんて書かれているのかわかるよね?
368デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:31:02.04ID:GD01KKAb
予想が完全に外れたID:8qqh3vKrを晒し上げ♪♪♪
ここまで簡単な予想を外すとかバカ過ぎて生きていけなさそうwww
馬鹿丸出しですねwwwwww
2021/12/24(金) 16:40:31.03ID:8qqh3vKr
素でバカなんだな。。もうコンパイル通ったんで俺の仕事終わりとか現場で言ってろよ。。話にもならん。
370デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:42:14.31ID:/xk3NPni
>>362
最低限の性質を満たしている⇔正解って言ってんじゃん。。何読んでんだよ。
なんでそんなに読み取れないの?
だからバカだっていうんだよ。
だからちゃんと日本語の勉強しましょうね。
371デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:45:16.93ID:/xk3NPni
>>369
なお予言を外したことについては一貫してノータッチwwwww
話をしたくないのは君だよねwwwwww
372デフォルトの名無しさん
垢版 |
2021/12/24(金) 16:46:19.44ID:/xk3NPni
>>369
同一人物だってことはバレバレだっつーの。バカ丸出し。wwwwwwwwww
2021/12/24(金) 17:12:05.04ID:jmk0MHfo
どうでもええわRustの話しろ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況