公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust
公式ドキュメント
https://www.rust-lang.org/learn
Web上の実行環境
https://play.rust-lang.org
※Rustを学びたい人はまず最初に公式のThe Bookを読むこと
https://doc.rust-lang.org/book/
※Rustを学ぶ際に犯しがちな12の過ち
https://dystroy.org/blog/how-not-to-learn-rust
※Rustのasyncについて知りたければ「async-book」は必読
https://rust-lang.github.io/async-book/
※次スレは原則>>980が立てること
前スレ
Rust part23
https://mevius.5ch.net/test/read.cgi/tech/1708677472/
Rust part24
レス数が950を超えています。1000を超えると書き込みができなくなります。
2024/05/27(月) 06:41:26.82ID:T4AFD1f4
851デフォルトの名無しさん
2024/07/14(日) 11:05:51.89ID:iqWqiKXK なぜ二種類あるのか?というと
長さ0だと最初の要素すらないため
reduceはOption型が返る特徴があります
例えば和を求める場合でも
長さ0だったらNoneになってほしいならば
reduce(|sum, n: i32| sum + n)
長さ0なら和が0となってほしいならば
fold(0, |sum, n: i32| sum + n)
と使い分けることができます
ちなみに後者はsum()メソッドが用意されています
長さ0だと最初の要素すらないため
reduceはOption型が返る特徴があります
例えば和を求める場合でも
長さ0だったらNoneになってほしいならば
reduce(|sum, n: i32| sum + n)
長さ0なら和が0となってほしいならば
fold(0, |sum, n: i32| sum + n)
と使い分けることができます
ちなみに後者はsum()メソッドが用意されています
852デフォルトの名無しさん
2024/07/14(日) 11:33:51.37ID:iqWqiKXK853デフォルトの名無しさん
2024/07/14(日) 12:47:51.97ID:JssLuzWj854デフォルトの名無しさん
2024/07/14(日) 12:50:40.22ID:JssLuzWj855デフォルトの名無しさん
2024/07/14(日) 12:54:55.73ID:JssLuzWj >>850
python の reduce は初期値を [0] にするのも任意に設定するのも
同じ reduce という名前でいけるのが
Rust だと reduce と fold で使い分ける必要があるということね
Rust が面倒だと言うことは理解した
python の reduce は初期値を [0] にするのも任意に設定するのも
同じ reduce という名前でいけるのが
Rust だと reduce と fold で使い分ける必要があるということね
Rust が面倒だと言うことは理解した
856デフォルトの名無しさん
2024/07/14(日) 13:21:58.79ID:iqWqiKXK >>855
そういうことではないよ
RustではOption型やResult型でエラーや異常値を含めて正しい状況を値として得られるんだよ
例えば長さ0で初期値なしの時に
Pythonだとエラーだよね
Rustは常に値として返してくれて今回はOption<Self::Item>型
そういうことではないよ
RustではOption型やResult型でエラーや異常値を含めて正しい状況を値として得られるんだよ
例えば長さ0で初期値なしの時に
Pythonだとエラーだよね
Rustは常に値として返してくれて今回はOption<Self::Item>型
857デフォルトの名無しさん
2024/07/14(日) 14:06:11.77ID:CpW1/GRz858デフォルトの名無しさん
2024/07/14(日) 14:15:44.82ID:iqWqiKXK Rustならrev().fold(...)だね
859デフォルトの名無しさん
2024/07/14(日) 15:28:53.80ID:QaC7oPd0 テンプレートが出てきたあたりからC++の勉強をやめたのだけど
これは「型を引数に取ってインスタンス化する」ということでおk?
それがトレイトをまたいだ場合、いつどこで誰が何してるか分からなくなる
ファイルをまたぐインライン関数みたいにソースレベルでなされること?
これは「型を引数に取ってインスタンス化する」ということでおk?
それがトレイトをまたいだ場合、いつどこで誰が何してるか分からなくなる
ファイルをまたぐインライン関数みたいにソースレベルでなされること?
860デフォルトの名無しさん
2024/07/14(日) 16:59:00.63ID:Q38o8Kq2 >>840
JavaとかC#の世界でも、interfaceが実装者に要求する条件を実装者が実際には満たさない、って場合にLSP違反って言われるの?
言われるよ
リスコフ本人が書いたJavaの本にも書いてある
JavaとかC#の世界でも、interfaceが実装者に要求する条件を実装者が実際には満たさない、って場合にLSP違反って言われるの?
言われるよ
リスコフ本人が書いたJavaの本にも書いてある
861デフォルトの名無しさん
2024/07/14(日) 17:32:49.60ID:Q38o8Kq2 >>839
>ドキュメントや付加assertなど一段上のメタ情報を用いなければ何も進めることができない
一段上のメタ情報であるspecificaitonを使いなさいというのがリスコフの教え
それがBehavioral SubtypingってものでLSPが伝えようとしてる原則だよ
>ドキュメントや付加assertなど一段上のメタ情報を用いなければ何も進めることができない
一段上のメタ情報であるspecificaitonを使いなさいというのがリスコフの教え
それがBehavioral SubtypingってものでLSPが伝えようとしてる原則だよ
862デフォルトの名無しさん
2024/07/14(日) 20:15:07.35ID:QaC7oPd0 ああ、なんだ
クレート=ELFファイルだと思ってたけど違うのね
クレート=ELFファイルだと思ってたけど違うのね
863デフォルトの名無しさん
2024/07/14(日) 23:33:04.31ID:jL63bGYb もちろんクレートはコンパイルしてELFに出来得る
865デフォルトの名無しさん
2024/07/15(月) 01:06:24.34ID:qZQFNGwo LLVMのバックエンドにCOFFもあるよ
866デフォルトの名無しさん
2024/07/15(月) 01:09:28.33ID:RXziJOxB LLVMの役割
ELFもCOFFもXCOFFもいける
ELFもCOFFもXCOFFもいける
867デフォルトの名無しさん
2024/07/15(月) 01:55:53.37ID:S6UfnUI4 >>860-861
なるほどね、本当に特定の言語処理系の型システムの実装が云々というところからは離れたところにある概念なんだ
あえて関連付けるなら、型システムの部分型付け関係がbehavioral subtypingにもなるように定義すべきであると
上位型が具体型であるために暗黙の条件が多数想定される状況では特にLSPを意識すべきだが、それに限定される概念ではないと
なるほどね、本当に特定の言語処理系の型システムの実装が云々というところからは離れたところにある概念なんだ
あえて関連付けるなら、型システムの部分型付け関係がbehavioral subtypingにもなるように定義すべきであると
上位型が具体型であるために暗黙の条件が多数想定される状況では特にLSPを意識すべきだが、それに限定される概念ではないと
868デフォルトの名無しさん
2024/07/15(月) 02:35:13.63ID:fmM+TfOR supertypeの実装がない場合は
LSPの不変条件・事前条件・事後条件などsubtypeの実装と比較しようがなく
LSPの対象になりようがないよね
LSPの不変条件・事前条件・事後条件などsubtypeの実装と比較しようがなく
LSPの対象になりようがないよね
869デフォルトの名無しさん
2024/07/15(月) 03:42:20.85ID:csp8v2ux docs.rs の左上のRマーク
今話題のRen4のマークに似てるね
今話題のRen4のマークに似てるね
870デフォルトの名無しさん
2024/07/15(月) 09:46:03.12ID:kpV4D65H コレクションしないんだから狭義には参照カウンタはGCとは言えない。
広義には含めてやってもいいが。
広義には含めてやってもいいが。
871デフォルトの名無しさん
2024/07/15(月) 11:20:28.28ID:qZQFNGwo ライブラリは.rlibまたは.rmetaで、これもELFやCOFFとは別物
ふむ
ふむ
872 警備員[Lv.1][新芽]
2024/07/15(月) 11:29:04.89ID:omk2e105 たしかにRマークってRustから周りのやつ外したような感じじゃん
873デフォルトの名無しさん
2024/07/15(月) 11:58:24.83ID:K85WsTqt Ren4のRマークはsans-serifのゴシック体だからRustのロゴとは全然違うだろ
本人のやる気、こだわりのなさをフォントで表現してるんだから
RustのRと一緒にしたら双方に失礼
本人のやる気、こだわりのなさをフォントで表現してるんだから
RustのRと一緒にしたら双方に失礼
874デフォルトの名無しさん
2024/07/15(月) 13:14:40.10ID:ZO/EZAih 単に好みの問題だけど
ウィルスっぽくて気持ち悪い
好きじゃない
ウィルスっぽくて気持ち悪い
好きじゃない
875デフォルトの名無しさん
2024/07/15(月) 14:14:44.43ID:ko+PCaVU >>874
元々サビ菌がモチーフやからしゃーない
元々サビ菌がモチーフやからしゃーない
876デフォルトの名無しさん
2024/07/15(月) 18:49:44.14ID:GgRIn2WF 独裁者にも見た目がダサい奴がよくいるけど言っても無駄だ
デザインの力とは全然違う別の力でねじ伏せてくる
デザインの力とは全然違う別の力でねじ伏せてくる
877デフォルトの名無しさん
2024/07/15(月) 19:16:07.61ID:Vjas5sQD ダサいという指摘に理由を説明しても、ダサいことは変わらないんだよな
言語がダサければ信者もダサい
うだうだ言いながらダサい服着てそう
言語がダサければ信者もダサい
うだうだ言いながらダサい服着てそう
878デフォルトの名無しさん
2024/07/15(月) 22:03:42.65ID:e+J3OGv0 イテレータ要素をヒープに格納するにはこれでいいんか
.fold(Vec::new(), |mut v, t| { v.push(t); v })
.fold(Vec::new(), |mut v, t| { v.push(t); v })
879デフォルトの名無しさん
2024/07/15(月) 22:12:32.29ID:S6UfnUI4 またイテレータの話してる
880デフォルトの名無しさん
2024/07/15(月) 22:50:12.36ID:9YaXaz6n >>878
collectしろや
collectしろや
881デフォルトの名無しさん
2024/07/15(月) 23:25:29.58ID:wT4qVw/w >>878
分かって書いてるかもだけど一応
let v = (0..10).collect::<Vec<i32>>();
コンテナにまとめるならこんな感じに collect を使う
例えば文字を走査するイテレーターをStringにcollectするようなことも可
型パラメーターは推論が効くのでそれに任せても良い
左辺に情報があるならcollectの型パラメーターはいらない
let v: Vec<i32> = (0..10).collect();
要素の型が分かるなら、右辺のコンテナの中身は_で推論させても良い
let v = (0i32..10).collect::<Vec<_>>();
分かって書いてるかもだけど一応
let v = (0..10).collect::<Vec<i32>>();
コンテナにまとめるならこんな感じに collect を使う
例えば文字を走査するイテレーターをStringにcollectするようなことも可
型パラメーターは推論が効くのでそれに任せても良い
左辺に情報があるならcollectの型パラメーターはいらない
let v: Vec<i32> = (0..10).collect();
要素の型が分かるなら、右辺のコンテナの中身は_で推論させても良い
let v = (0i32..10).collect::<Vec<_>>();
882デフォルトの名無しさん
2024/07/15(月) 23:35:20.09ID:nug4GWMJ クロージャにキャプチャさせれば既存ベクタへ格納も追加もできる
let mut v = Vec::new();
iter.fold((), |_, t| v.push(t));
しかしこれではfold使ってる意味がなくこれと一緒
iter.for_each(|t| v.push(t));
もちろん正解は既存Vecへ追加なら
v.extend(iter);
新規にVecへ収集なら
let v = iter.collect::<Vec<_>>();
let mut v = Vec::new();
iter.fold((), |_, t| v.push(t));
しかしこれではfold使ってる意味がなくこれと一緒
iter.for_each(|t| v.push(t));
もちろん正解は既存Vecへ追加なら
v.extend(iter);
新規にVecへ収集なら
let v = iter.collect::<Vec<_>>();
883デフォルトの名無しさん
2024/07/16(火) 23:25:36.51ID:ab19AXDr Foo::from_iter(iter)でもいいね
例えばVec::from_iter(iter)
特にIntoIteratorな時にinto_iter()を省けて見やすいよ
例えばVec::from_iter(iter)
特にIntoIteratorな時にinto_iter()を省けて見やすいよ
884デフォルトの名無しさん
2024/07/17(水) 18:51:22.39ID:Hw1cPZyQ イテレータをcollectしたい場合と
イテレータではないIntoIteratorを別の構造体に変換したい場合とは文脈が違うでしょ
from_iterを直接呼ぶのは基本的に後者
前者の場合にターボフィッシュ書かなくてもいいという理由で
from_iterを直接呼ぶのはidiomaticではない
イテレータではないIntoIteratorを別の構造体に変換したい場合とは文脈が違うでしょ
from_iterを直接呼ぶのは基本的に後者
前者の場合にターボフィッシュ書かなくてもいいという理由で
from_iterを直接呼ぶのはidiomaticではない
885デフォルトの名無しさん
2024/07/17(水) 21:48:43.22ID:3eay5eeN 前者のケースでfrom_iterを直接呼んでても分かるから別にいいよ
自分で書くときはcollect使うけど
自分で書くときはcollect使うけど
886デフォルトの名無しさん
2024/07/17(水) 23:54:54.61ID:zgRAxdKk これは短い方がいい
let x = HashMap::<_, _>::from_iter(vec);
let x = vec.into_iter().collect::<HashMap::<_, _>>();
let x = HashMap::<_, _>::from_iter(vec);
let x = vec.into_iter().collect::<HashMap::<_, _>>();
887デフォルトの名無しさん
2024/07/17(水) 23:55:29.92ID:zgRAxdKk これはほぼ長さ変わらないからどちらがわかりやすいか
let x = HashMap::<_, _>::from_iter(iter);
let x = iter.collect::<HashMap::<_, _>>();
let x = HashMap::<_, _>::from_iter(iter);
let x = iter.collect::<HashMap::<_, _>>();
888デフォルトの名無しさん
2024/07/18(木) 01:10:31.87ID:CNIyJc+8 どちらも一度変数で受ける形になるので型アノテーションが必要なら
let x: HashMap<_, _> のように基本的には左辺に書く
HashMapなら型パラメータ部分も推論に頼らず
明示的に書くことのほうが多いかもしれない
イテレータをcollectしたい場合というのは
イテレータのメソッドチェーンで各種処理をしてから
最終的にcollectする形になることが多いから
from_iterの直呼びじゃなくcollectが好まれる
let x: HashMap<_, _> のように基本的には左辺に書く
HashMapなら型パラメータ部分も推論に頼らず
明示的に書くことのほうが多いかもしれない
イテレータをcollectしたい場合というのは
イテレータのメソッドチェーンで各種処理をしてから
最終的にcollectする形になることが多いから
from_iterの直呼びじゃなくcollectが好まれる
889デフォルトの名無しさん
2024/07/18(木) 02:40:28.19ID:0QBRSK+b ところでchronoって、しょっちゅうAPIが変わるし
やたら冗長な書き方になるし結構クソじゃない?
やたら冗長な書き方になるし結構クソじゃない?
890デフォルトの名無しさん
2024/07/18(木) 12:05:40.95ID:WL/aeG4d 書き方が気に入らないならtime-rsを試してみたら?
891デフォルトの名無しさん
2024/07/18(木) 21:07:48.37ID:2m7Ost/Q なるほど
trait Iterator {
type Item;
fn collect<B: FromIterator<Self::Item>>(self) -> B
where
Self: Sized,
{
FromIterator::from_iter(self)
}
}
trait Iterator {
type Item;
fn collect<B: FromIterator<Self::Item>>(self) -> B
where
Self: Sized,
{
FromIterator::from_iter(self)
}
}
892デフォルトの名無しさん
2024/07/18(木) 23:31:33.62ID:GQ1B8wHA 代数的データ型ってなんかすごいけど知名度がモナドより低いな
893デフォルトの名無しさん
2024/07/19(金) 02:03:52.09ID:MUvBupZH >>890
使ってみたけど、time-rsいいね
いつのまにかダウンロード数でchronoを上回る競合があったとは知らんかった
タイムゾーンの扱いがやや簡略化されてるけど、夏時間のない日本人的には問題ない
月を直接intで指定できないのが英語仕様やな……ってちょっと気になる
使ってみたけど、time-rsいいね
いつのまにかダウンロード数でchronoを上回る競合があったとは知らんかった
タイムゾーンの扱いがやや簡略化されてるけど、夏時間のない日本人的には問題ない
月を直接intで指定できないのが英語仕様やな……ってちょっと気になる
894デフォルトの名無しさん
2024/07/19(金) 03:51:08.70ID:riLGg6QV >>891
この各収納先への移譲と両側のトレイト境界が汎用化の肝
trait FromIterator<A>: Sized {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
この各収納先への移譲と両側のトレイト境界が汎用化の肝
trait FromIterator<A>: Sized {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
895デフォルトの名無しさん
2024/07/19(金) 06:06:24.35ID:LryDU6eW Rustはジェネリックとトレイト境界と抽象的なデフォルト実装のおかげで
安全で利便性の高いコードの汎用共通化に成功していますね
安全で利便性の高いコードの汎用共通化に成功していますね
896デフォルトの名無しさん
2024/07/19(金) 23:21:36.34ID:rC6z5NUh cloud strike のはテロルやね
897デフォルトの名無しさん
2024/07/19(金) 23:30:11.35ID:rC6z5NUh898デフォルトの名無しさん
2024/07/19(金) 23:52:20.75ID:8WlCJE3Q >>897
エラーとなりますた
エラーとなりますた
899デフォルトの名無しさん
2024/07/20(土) 00:12:48.41ID:bNknJoN/ >>896
ウィルスバスター以来の快挙やね
ウィルスバスター以来の快挙やね
900デフォルトの名無しさん
2024/07/20(土) 14:16:49.05ID:F167yFzL901デフォルトの名無しさん
2024/07/20(土) 23:38:20.92ID:6EAP68vq902デフォルトの名無しさん
2024/07/21(日) 01:48:23.56ID:eUhj6//q ★┷┓
┃D┃
┃D┃
┃K┃
┃で┃
┃も┃
┃r┃
┃u┃
┃s┃
┃t┃
┃が┃
┃使┃
┃え┃
┃ま┃
┃す┃
┃よ┃
┃う┃
┃に┃
┗━★
┃D┃
┃D┃
┃K┃
┃で┃
┃も┃
┃r┃
┃u┃
┃s┃
┃t┃
┃が┃
┃使┃
┃え┃
┃ま┃
┃す┃
┃よ┃
┃う┃
┃に┃
┗━★
903デフォルトの名無しさん
2024/07/21(日) 09:43:03.00ID:QhoywuRk904デフォルトの名無しさん
2024/07/21(日) 10:14:17.60ID:TGGT0XLq とあるライブラリに変な癖があるという話は
どの言語でもあるからそういう話ではないだろ
どの言語でもあるからそういう話ではないだろ
905デフォルトの名無しさん
2024/07/21(日) 10:29:10.85ID:U3c7smqS イテレータ使ったことない
906デフォルトの名無しさん
2024/07/21(日) 10:35:28.58ID:W0nR4Dwz >>903
Rustはその点シンプルでクセもなく覚えやすい
基本的に複数の要素ならFromIterator
VecでもHashMapでも何でもいける
複数のcharやstrなどからString作成もいける
複数のstrやStringやPathなどからPathBuf作成もいける
Fromは基本的に単独要素や配列(=静的固定長)から他へ変換
Rustはその点シンプルでクセもなく覚えやすい
基本的に複数の要素ならFromIterator
VecでもHashMapでも何でもいける
複数のcharやstrなどからString作成もいける
複数のstrやStringやPathなどからPathBuf作成もいける
Fromは基本的に単独要素や配列(=静的固定長)から他へ変換
907デフォルトの名無しさん
2024/07/21(日) 11:03:59.33ID:BMrg5vDt908デフォルトの名無しさん
2024/07/21(日) 11:04:04.35ID:xuKRyHnL >>903
それくらいchatGPTで教えてもらえるだろ
それくらいchatGPTで教えてもらえるだろ
909デフォルトの名無しさん
2024/07/21(日) 11:14:46.17ID:BMrg5vDt >>908
俺もそう思って試してみたけど駄目だね
エラーの簡単な原因とcollect使えみたいな代替案は出してくるけど
根本的な理解につながる答えを返せないだけでなくいろいろと間違った情報を返してくる
俺もそう思って試してみたけど駄目だね
エラーの簡単な原因とcollect使えみたいな代替案は出してくるけど
根本的な理解につながる答えを返せないだけでなくいろいろと間違った情報を返してくる
910デフォルトの名無しさん
2024/07/21(日) 11:48:09.12ID:W0nR4Dwz from_iter(array)で済むのに
なぜ配列からHashMapへのFromがあるのか理由はおそらく
配列からmoveするinto_iter()が数年前までなかったためだと思う
今は配列を含めて要素が複数なら→イテレータ利用→FromIteratorと覚えればよいかと
なぜ配列からHashMapへのFromがあるのか理由はおそらく
配列からmoveするinto_iter()が数年前までなかったためだと思う
今は配列を含めて要素が複数なら→イテレータ利用→FromIteratorと覚えればよいかと
911デフォルトの名無しさん
2024/07/21(日) 11:54:05.33ID:9I2odrUJ そもそもイテレーターとコンテナの概念を勘違いしてる可能性ありそう
別種のコンテナ同士の変換は (特別な対応がない限り) 直接的には無理で、イテレーターを介して中身の要素を走査すれば渡せるということ
みかん箱を冷蔵庫に変換することはできないけど、箱の中のみかんを1つずつ取り出して、それを冷蔵庫型に纏める (collect) ことはできるような感じ
別種のコンテナ同士の変換は (特別な対応がない限り) 直接的には無理で、イテレーターを介して中身の要素を走査すれば渡せるということ
みかん箱を冷蔵庫に変換することはできないけど、箱の中のみかんを1つずつ取り出して、それを冷蔵庫型に纏める (collect) ことはできるような感じ
912デフォルトの名無しさん
2024/07/21(日) 12:08:53.38ID:QhoywuRk 今回は >>910 さんをベストアンサーとさせて頂きます
みなさんご協力ありがとうございました
みなさんご協力ありがとうございました
913デフォルトの名無しさん
2024/07/21(日) 12:17:32.86ID:rbHgMj6q >>911
それは単に抽象度の違いであって勘違いでも何でもない
それは単に抽象度の違いであって勘違いでも何でもない
914デフォルトの名無しさん
2024/07/21(日) 12:17:32.92ID:QhoywuRk >>911
勘違いはしてない
use std::collections::HashMap;
use std::iter::FromIterator;
fn main() {
let u = vec![("hoge", 1), ("fuga", 2)];
let x: HashMap::<_, _> = u.into_iter().collect();
println!("{:?}", x);
let v = vec![("hoge", 1), ("fuga", 2)];
let y = HashMap::<_, _>::from_iter(v); // use std::iter::FromIterator
println!("{:?}", y);
let w = [("hoge", 1), ("fuga", 2)]; // array
let z = HashMap::<_, _>::from(w);
println!("{:?}", z);
}
勘違いはしてない
use std::collections::HashMap;
use std::iter::FromIterator;
fn main() {
let u = vec![("hoge", 1), ("fuga", 2)];
let x: HashMap::<_, _> = u.into_iter().collect();
println!("{:?}", x);
let v = vec![("hoge", 1), ("fuga", 2)];
let y = HashMap::<_, _>::from_iter(v); // use std::iter::FromIterator
println!("{:?}", y);
let w = [("hoge", 1), ("fuga", 2)]; // array
let z = HashMap::<_, _>::from(w);
println!("{:?}", z);
}
915デフォルトの名無しさん
2024/07/21(日) 12:21:47.94ID:QhoywuRk なぜ Vec から HashMap は from が使えないのか?
の問いに GPT は答えてくれない
の問いに GPT は答えてくれない
916デフォルトの名無しさん
2024/07/21(日) 12:29:53.31ID:+gih9iRs917デフォルトの名無しさん
2024/07/21(日) 12:32:17.29ID:BMrg5vDt918デフォルトの名無しさん
2024/07/21(日) 13:57:28.77ID:W0nR4Dwz >>916
ありがと
調べたらその順だね
そうなるとFrom<配列>だけを特別に用意した理由は配列が基本型だからだろうか
HashMap::from(array)のコードを見ると
HashMap::from_iter(array)とFromIteratorの実装を呼び出すだけなので
ありがと
調べたらその順だね
そうなるとFrom<配列>だけを特別に用意した理由は配列が基本型だからだろうか
HashMap::from(array)のコードを見ると
HashMap::from_iter(array)とFromIteratorの実装を呼び出すだけなので
919デフォルトの名無しさん
2024/07/21(日) 16:06:46.61ID:nMuf3u03 MapやSetのリテラルがないけどリテラルに近い感覚で初期化したい場合の代替策として用意されたのがFromの実装
920デフォルトの名無しさん
2024/07/21(日) 16:20:17.13ID:BJsLblxy _iterの5文字が節約できるメリットだけか
921デフォルトの名無しさん
2024/07/21(日) 16:39:36.83ID:u5tRysNp >>920
タイプアノテーションの要不要があるのでもっと節約できるよ
タイプアノテーションの要不要があるのでもっと節約できるよ
922デフォルトの名無しさん
2024/07/21(日) 16:43:19.24ID:BJsLblxy >>921
不要になる例を出して
不要になる例を出して
923デフォルトの名無しさん
2024/07/21(日) 17:05:45.63ID:QAZ3DYjh FromがあるとIntoが使えるからHashMap返すときとか引数で渡すときに
HashMap::from([..])
の代わりに
[..].into()
で書ける
型を明記するletだと大差ないかも
let map: HashMap<K, V> = [..].into();
let map = HashMap::<K, V>::from([..]);
HashMap::from([..])
の代わりに
[..].into()
で書ける
型を明記するletだと大差ないかも
let map: HashMap<K, V> = [..].into();
let map = HashMap::<K, V>::from([..]);
924デフォルトの名無しさん
2024/07/21(日) 17:22:33.98ID:BJsLblxy >>923
そこでタイプアノテーションが不要になる例はないよな
関数の引数型か返り型に書いている
into()と書ける件も
collect()と書けるから
FromIteratorに対してFromもあるメリットは3文字節約できるだけか
そこでタイプアノテーションが不要になる例はないよな
関数の引数型か返り型に書いている
into()と書ける件も
collect()と書けるから
FromIteratorに対してFromもあるメリットは3文字節約できるだけか
925デフォルトの名無しさん
2024/07/21(日) 21:02:32.72ID:eUhj6//q dyn traits以外にinto使うなよ。変換するんだから
let s = "Hello, world!";
let string = Into::<String>::into(s);
じゃなくて
let s = "Hello, world!";
let string = String::form(s);
だろ。
let s = "Hello, world!";
let string = Into::<String>::into(s);
じゃなくて
let s = "Hello, world!";
let string = String::form(s);
だろ。
926デフォルトの名無しさん
2024/07/21(日) 21:07:32.49ID:BUmQiTHC は?
927デフォルトの名無しさん
2024/07/21(日) 22:10:59.79ID:kEjkNYpd >>922
use std::collections::HashMap;
fn main() {
let xs = [(1, "a"), (2, "b"), (3, "c")];
let map = HashMap::from(xs);
println!("{:?}", map);
}
use std::collections::HashMap;
fn main() {
let xs = [(1, "a"), (2, "b"), (3, "c")];
let map = HashMap::from(xs);
println!("{:?}", map);
}
928デフォルトの名無しさん
2024/07/21(日) 22:23:54.17ID:vNf5wQaP >>927
HashMap::from_iter(xs)で十分じゃね
HashMap::from_iter(xs)で十分じゃね
929デフォルトの名無しさん
2024/07/21(日) 22:30:45.10ID:kEjkNYpd >>928
error[E0283]: type annotations needed for `HashMap<i32, &str, _>`
--> src/main.rs:5:9
|
5 | let map = HashMap::from_iter(xs);
| ^^^ ------- type must be known at this point
|
error[E0283]: type annotations needed for `HashMap<i32, &str, _>`
--> src/main.rs:5:9
|
5 | let map = HashMap::from_iter(xs);
| ^^^ ------- type must be known at this point
|
930デフォルトの名無しさん
2024/07/22(月) 12:16:14.88ID:7a9cZObY 配列からのFromは機能が制限されている
struct HashMap<K, V, S = RandomState> { ... }
impl<K: Eq + Hash, V, S: BuildHasher + Default> FromIterator<(K, V)> for HashMap<K, V, S> { ... }
impl<K: Eq + Hash, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState> { ... }
struct HashMap<K, V, S = RandomState> { ... }
impl<K: Eq + Hash, V, S: BuildHasher + Default> FromIterator<(K, V)> for HashMap<K, V, S> { ... }
impl<K: Eq + Hash, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState> { ... }
931デフォルトの名無しさん
2024/07/22(月) 12:18:01.98ID:7a9cZObY つまりFromは重いデフォルトハッシャーに固定されてしまっている
FromIteratorを使えば自由に速いものを利用できる
let xxx = HashMap::<_, _, FxHash>::from_iter(array);
FromIteratorを使えば自由に速いものを利用できる
let xxx = HashMap::<_, _, FxHash>::from_iter(array);
932デフォルトの名無しさん
2024/07/23(火) 01:07:15.84ID:XvQFw5Nb HashMap::from(配列)の場合は
デフォルトハッシャーで困るユースケースは稀だから
APIのエルゴノミクスのために意図的にRandomStateに固定してる
そのおかけでタイプアノテーションなしで書ける
タイプアノテーション無しの場合はデフォルト指定の型を優先的に使うよう
Rustのコンパイラが改良されればこの辺の差はなくなる
デフォルトハッシャーで困るユースケースは稀だから
APIのエルゴノミクスのために意図的にRandomStateに固定してる
そのおかけでタイプアノテーションなしで書ける
タイプアノテーション無しの場合はデフォルト指定の型を優先的に使うよう
Rustのコンパイラが改良されればこの辺の差はなくなる
933デフォルトの名無しさん
2024/07/23(火) 01:10:26.97ID:XvQFw5Nb >>931
>let xxx = HashMap::<_, _, FxHash>::from_iter(array);
FxHashのところはFxBuildHasherだね
let xxx = FxHashMap::from_iter(array);と書いたほうがいろいろ親切
親切設計のライブラリなら
let xxx = AHashMap::from(array);
のようにFromIteratorだけでなくFromも使える
>let xxx = HashMap::<_, _, FxHash>::from_iter(array);
FxHashのところはFxBuildHasherだね
let xxx = FxHashMap::from_iter(array);と書いたほうがいろいろ親切
親切設計のライブラリなら
let xxx = AHashMap::from(array);
のようにFromIteratorだけでなくFromも使える
934デフォルトの名無しさん
2024/07/23(火) 01:31:49.01ID:Rfg4Mjqa tupleをiteratorしたいんだが無理?
935デフォルトの名無しさん
2024/07/23(火) 02:50:50.92ID:l+hNtTPE こういう意味?
let t = ("abcde", "fghijkl", "mno", "pqrstuvw", "xyz");
assert_eq!("abcdefghijklmnopqrstuvwxyz", Into::<[_; 5]>::into(t).into_iter().collect::<String>());
let t = ("abcde", "fghijkl", "mno", "pqrstuvw", "xyz");
assert_eq!("abcdefghijklmnopqrstuvwxyz", Into::<[_; 5]>::into(t).into_iter().collect::<String>());
936デフォルトの名無しさん
2024/07/23(火) 09:22:40.63ID:iSDzXJU2 同じ型だけの要素で構成されるtupleならいけそうだけど
色んな型ば混ざってるtupleはエラー出そう
色んな型ば混ざってるtupleはエラー出そう
937デフォルトの名無しさん
2024/07/23(火) 11:25:10.18ID:ijWLrFq+ dynにすれば色んな型を混ぜられる
関数から返すときはBox<dyn ...>にする
例えば数値と文字列が混じる有名な例をRustでdynを使って書くと
type FizzBuzz = Box<dyn std::fmt::Display>;
fn fizz_buzz_iter() -> impl Iterator<Item=FizzBuzz> {
(1..).map(|int| match (int % 3, int % 5) {
(0, 0) => Box::new("FizzBuzz") as FizzBuzz,
(0, _) => Box::new("Fizz"),
(_, 0) => Box::new("Buzz"),
(_, _) => Box::new(int),
})
}
fn main() {
for x in fizz_buzz_iter().take(30) {
println!("{x}");
}
}
関数から返すときはBox<dyn ...>にする
例えば数値と文字列が混じる有名な例をRustでdynを使って書くと
type FizzBuzz = Box<dyn std::fmt::Display>;
fn fizz_buzz_iter() -> impl Iterator<Item=FizzBuzz> {
(1..).map(|int| match (int % 3, int % 5) {
(0, 0) => Box::new("FizzBuzz") as FizzBuzz,
(0, _) => Box::new("Fizz"),
(_, 0) => Box::new("Buzz"),
(_, _) => Box::new(int),
})
}
fn main() {
for x in fizz_buzz_iter().take(30) {
println!("{x}");
}
}
938デフォルトの名無しさん
2024/07/23(火) 17:24:06.93ID:hqmWVJB3 またFizzBuzzイテレータ書いてる……
939デフォルトの名無しさん
2024/07/23(火) 21:36:57.26ID:1jhTJKzb940デフォルトの名無しさん
2024/07/23(火) 21:58:12.50ID:joaeWjir941デフォルトの名無しさん
2024/07/23(火) 23:07:54.81ID:tKFzmUCx ほとんどの言語でオブジェクトを返す時にヒープを使うから
RustでもBox<dyn>を使っても構わないけど
ライフタイムさえ満たしてやればヒープを使わずに&dynにできるよ
use std::fmt::Display;
type FizzBuzz<'a> = &'a dyn Display;
fn fizz_buzz_iter<'a, T: Display>(i: &'a[T], s: &'a[&str; 3]) -> impl Iterator<Item = FizzBuzz<'a>> {
(1..).map_while(|int| match (int % 3, int % 5) {
(0, 0) => Some(&s[0] as FizzBuzz),
(0, _) => Some(&s[1]),
(_, 0) => Some(&s[2]),
(_, _) => i.get(int).map(|int| int as FizzBuzz),
})
}
fn main() {
let i: [_; 256] = std::array::from_fn(|i| i as u8);
let s: [_; 3] = ["FizzBuzz", "Fizz", "Buzz"];
for x in fizz_buzz_iter(&i, &s).take(30) {
println!("{x}");
}
}
RustでもBox<dyn>を使っても構わないけど
ライフタイムさえ満たしてやればヒープを使わずに&dynにできるよ
use std::fmt::Display;
type FizzBuzz<'a> = &'a dyn Display;
fn fizz_buzz_iter<'a, T: Display>(i: &'a[T], s: &'a[&str; 3]) -> impl Iterator<Item = FizzBuzz<'a>> {
(1..).map_while(|int| match (int % 3, int % 5) {
(0, 0) => Some(&s[0] as FizzBuzz),
(0, _) => Some(&s[1]),
(_, 0) => Some(&s[2]),
(_, _) => i.get(int).map(|int| int as FizzBuzz),
})
}
fn main() {
let i: [_; 256] = std::array::from_fn(|i| i as u8);
let s: [_; 3] = ["FizzBuzz", "Fizz", "Buzz"];
for x in fizz_buzz_iter(&i, &s).take(30) {
println!("{x}");
}
}
942デフォルトの名無しさん
2024/07/23(火) 23:38:39.26ID:QoNSkCmh 「tupleでイテレートできないの?」という質問に「こういうイテレータなら異なる型を混ぜられるよ」と回答するあたりがいかにもな感じ
率直に「できる/できない」で回答した上で補足として書けばいいのに
率直に「できる/できない」で回答した上で補足として書けばいいのに
943デフォルトの名無しさん
2024/07/23(火) 23:40:03.74ID:38zrS1+w トレイトオブジェクトをdynと呼ぶのは複オジだけ
944デフォルトの名無しさん
2024/07/23(火) 23:40:30.32ID:38zrS1+w >>942
それな
それな
945デフォルトの名無しさん
2024/07/23(火) 23:49:18.56ID:lLea54if Rust 2018 editionからdyn必須に変わった
946デフォルトの名無しさん
2024/07/24(水) 00:02:23.05ID:QMkBbV1F できる/できないで言えばできるよ
タプルの要素がすべて同じ型で要素数が12個以内ならFrom/Intoで配列に変換してイテレートする
それ以外ならextension traitで自前のイテレータを返すメソッドをタプルに実装する
他にも方法あるけどこの2つが主
タプルの型・要素数、イテレート時の型を汎用化したい場合はマクロが必須でそこそこめんどくさい
特にヘテロなタプルを汎用的にイテレート用の型に揃えるのはめんどくさい
本当にタプルで管理するのが望ましいのか
タプルで管理しつつイテレータで回すのがベストなのか
まずはよく考えたほうがいいと思う
タプルの要素がすべて同じ型で要素数が12個以内ならFrom/Intoで配列に変換してイテレートする
それ以外ならextension traitで自前のイテレータを返すメソッドをタプルに実装する
他にも方法あるけどこの2つが主
タプルの型・要素数、イテレート時の型を汎用化したい場合はマクロが必須でそこそこめんどくさい
特にヘテロなタプルを汎用的にイテレート用の型に揃えるのはめんどくさい
本当にタプルで管理するのが望ましいのか
タプルで管理しつつイテレータで回すのがベストなのか
まずはよく考えたほうがいいと思う
947デフォルトの名無しさん
2024/07/24(水) 00:15:33.28ID:sAqPevwn dynを使えば型が何種類でもいけてトレイト境界も使えて楽だろうけどdynは重い
Fizz Buzzのように2種類の型で済むならEitherを使う
色んなトレイトを透過的に対応してくれている
use either::Either::{self, Left, Right};
type FizzBuzz = Either<usize, &'static str>;
fn fizz_buzz_iter() -> impl Iterator<Item = FizzBuzz> {
(1..).map(|int| match (int % 3, int % 5) {
(0, 0) => Right("FizzBuzz"),
(0, _) => Right("Fizz"),
(_, 0) => Right("Buzz"),
(_, _) => Left(int),
})
}
Fizz Buzzのように2種類の型で済むならEitherを使う
色んなトレイトを透過的に対応してくれている
use either::Either::{self, Left, Right};
type FizzBuzz = Either<usize, &'static str>;
fn fizz_buzz_iter() -> impl Iterator<Item = FizzBuzz> {
(1..).map(|int| match (int % 3, int % 5) {
(0, 0) => Right("FizzBuzz"),
(0, _) => Right("Fizz"),
(_, 0) => Right("Buzz"),
(_, _) => Left(int),
})
}
948デフォルトの名無しさん
2024/07/24(水) 00:35:21.34ID:UKniupNy リフレクションのサポートとかにもっと力入れてれば普通にできるんだろうけど、しゃあなし
Rustはそういうの好かない言語だから
Rustはそういうの好かない言語だから
950デフォルトの名無しさん
2024/07/24(水) 03:12:39.74ID:s3z853Sv >>940
タプルをイテレーションしたい…。
リストとか、配列みたいに使いってことですよね?
Haskellでは無理ですが、Rustでは可能なのでしょうか?
(構造体代わりと言った通り、構造体をイテレーションしようと思わないですよね?)
Python,RubyのリストとHaskellのそれみたいに、そもそもの意味が違う可能性もありますし…。
タプルをイテレーションしたい…。
リストとか、配列みたいに使いってことですよね?
Haskellでは無理ですが、Rustでは可能なのでしょうか?
(構造体代わりと言った通り、構造体をイテレーションしようと思わないですよね?)
Python,RubyのリストとHaskellのそれみたいに、そもそもの意味が違う可能性もありますし…。
951デフォルトの名無しさん
2024/07/24(水) 03:25:04.27ID:sCVmnNU/ >>935
let t = ("abcde", 123, "mno", "pqrstuvw", 456);
for e Into::<[_; 5]>::into(t).into_iter() {
println!("{:?}", e)
}
無理ポorz
let t = ("abcde", 123, "mno", "pqrstuvw", 456);
for e Into::<[_; 5]>::into(t).into_iter() {
println!("{:?}", e)
}
無理ポorz
レス数が950を超えています。1000を超えると書き込みができなくなります。
ニュース
