[過去ログ] Rust part24 (1002レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
1(2): 2024/05/27(月)06:41 ID:T4AFD1f4(1/3) AAS
公式
外部リンク:www.rust-lang.org
外部リンク:blog.rust-lang.org
外部リンク:github.com
公式ドキュメント
外部リンク:www.rust-lang.org
Web上の実行環境
外部リンク:play.rust-lang.org
※Rustを学びたい人はまず最初に公式のThe Bookを読むこと
外部リンク:doc.rust-lang.org
※Rustを学ぶ際に犯しがちな12の過ち
外部リンク:dystroy.org
※Rustのasyncについて知りたければ「async-book」は必読
外部リンク:rust-lang.github.io
※次スレは原則>>980が立てること
前スレ
Rust part23
2chスレ:tech
876: 2024/07/15(月)18:49 ID:GgRIn2WF(1) AAS
独裁者にも見た目がダサい奴がよくいるけど言っても無駄だ
デザインの力とは全然違う別の力でねじ伏せてくる
877: 2024/07/15(月)19:16 ID:Vjas5sQD(1) AAS
ダサいという指摘に理由を説明しても、ダサいことは変わらないんだよな
言語がダサければ信者もダサい
うだうだ言いながらダサい服着てそう
878(2): 2024/07/15(月)22:03 ID:e+J3OGv0(1) AAS
イテレータ要素をヒープに格納するにはこれでいいんか
.fold(Vec::new(), |mut v, t| { v.push(t); v })
879: 2024/07/15(月)22:12 ID:S6UfnUI4(2/2) AAS
またイテレータの話してる
880: 2024/07/15(月)22:50 ID:9YaXaz6n(1) AAS
>>878
collectしろや
881: 2024/07/15(月)23:25 ID:wT4qVw/w(1) AAS
>>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<_>>();
882: 2024/07/15(月)23:35 ID:nug4GWMJ(1) AAS
クロージャにキャプチャさせれば既存ベクタへ格納も追加もできる
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 ID:ab19AXDr(1) AAS
Foo::from_iter(iter)でもいいね
例えばVec::from_iter(iter)
特にIntoIteratorな時にinto_iter()を省けて見やすいよ
884: 2024/07/17(水)18:51 ID:Hw1cPZyQ(1) AAS
イテレータをcollectしたい場合と
イテレータではないIntoIteratorを別の構造体に変換したい場合とは文脈が違うでしょ
from_iterを直接呼ぶのは基本的に後者
前者の場合にターボフィッシュ書かなくてもいいという理由で
from_iterを直接呼ぶのはidiomaticではない
885: 2024/07/17(水)21:48 ID:3eay5eeN(1) AAS
前者のケースでfrom_iterを直接呼んでても分かるから別にいいよ
自分で書くときはcollect使うけど
886(1): 2024/07/17(水)23:54 ID:zgRAxdKk(1/2) AAS
これは短い方がいい
let x = HashMap::<_, _>::from_iter(vec);
let x = vec.into_iter().collect::<HashMap::<_, _>>();
887: 2024/07/17(水)23:55 ID:zgRAxdKk(2/2) AAS
これはほぼ長さ変わらないからどちらがわかりやすいか
let x = HashMap::<_, _>::from_iter(iter);
let x = iter.collect::<HashMap::<_, _>>();
888: 2024/07/18(木)01:10 ID:CNIyJc+8(1) AAS
どちらも一度変数で受ける形になるので型アノテーションが必要なら
let x: HashMap<_, _> のように基本的には左辺に書く
HashMapなら型パラメータ部分も推論に頼らず
明示的に書くことのほうが多いかもしれない
イテレータをcollectしたい場合というのは
イテレータのメソッドチェーンで各種処理をしてから
最終的にcollectする形になることが多いから
from_iterの直呼びじゃなくcollectが好まれる
889(1): 2024/07/18(木)02:40 ID:0QBRSK+b(1) AAS
ところでchronoって、しょっちゅうAPIが変わるし
やたら冗長な書き方になるし結構クソじゃない?
890(1): 2024/07/18(木)12:05 ID:WL/aeG4d(1) AAS
書き方が気に入らないならtime-rsを試してみたら?
891(1): 2024/07/18(木)21:07 ID:2m7Ost/Q(1) AAS
なるほど
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 ID:GQ1B8wHA(1) AAS
代数的データ型ってなんかすごいけど知名度がモナドより低いな
893: 2024/07/19(金)02:03 ID:MUvBupZH(1) AAS
>>890
使ってみたけど、time-rsいいね
いつのまにかダウンロード数でchronoを上回る競合があったとは知らんかった
タイムゾーンの扱いがやや簡略化されてるけど、夏時間のない日本人的には問題ない
月を直接intで指定できないのが英語仕様やな……ってちょっと気になる
894: 2024/07/19(金)03:51 ID:riLGg6QV(1) AAS
>>891
この各収納先への移譲と両側のトレイト境界が汎用化の肝
trait FromIterator<A>: Sized {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
895: 2024/07/19(金)06:06 ID:LryDU6eW(1) AAS
Rustはジェネリックとトレイト境界と抽象的なデフォルト実装のおかげで
安全で利便性の高いコードの汎用共通化に成功していますね
896(1): 2024/07/19(金)23:21 ID:rC6z5NUh(1/2) AAS
cloud strike のはテロルやね
897(3): 2024/07/19(金)23:30 ID:rC6z5NUh(2/2) AAS
>>886
let x; HashMap::<_, _> = vec.try_into()?;
>>889
+1
898(1): 2024/07/19(金)23:52 ID:8WlCJE3Q(1) AAS
>>897
エラーとなりますた
899(1): 2024/07/20(土)00:12 ID:bNknJoN/(1) AAS
>>896
ウィルスバスター以来の快挙やね
900: 2024/07/20(土)14:16 ID:F167yFzL(1) AAS
>>898
; が : の間違いかな
>>899
暴落予想
note.com/asset_n_ichi/n/nceaa6f318b1e
901(1): 2024/07/20(土)23:38 ID:6EAP68vq(1) AAS
>>897
HashMapとVecにTryFromが実装されていないから無理
FromIteratorが実装されているのでそれを使う
902: 2024/07/21(日)01:48 ID:eUhj6//q(1/2) AAS
AA省
903(3): 2024/07/21(日)09:43 ID:QhoywuRk(1/4) AAS
>>901
こういうのが「Rustは学習コストが高い」って言われる原因なんだろうな
答えを知ってる人は判ってても答えを知らない人は判らない
答えを調べるのにコストがかかりすぎる
904: 2024/07/21(日)10:14 ID:TGGT0XLq(1) AAS
とあるライブラリに変な癖があるという話は
どの言語でもあるからそういう話ではないだろ
905: 2024/07/21(日)10:29 ID:U3c7smqS(1) AAS
イテレータ使ったことない
906: 2024/07/21(日)10:35 ID:W0nR4Dwz(1/3) AAS
>>903
Rustはその点シンプルでクセもなく覚えやすい
基本的に複数の要素ならFromIterator
VecでもHashMapでも何でもいける
複数のcharやstrなどからString作成もいける
複数のstrやStringやPathなどからPathBuf作成もいける
Fromは基本的に単独要素や配列(=静的固定長)から他へ変換
907: 2024/07/21(日)11:03 ID:BMrg5vDt(1/3) AAS
>>903
>>897のはコンパイルエラーの内容が読めればすぐわかる
エラーの内容が読める程度の基礎力は最初に勉強して身につける必要がある
そもそもtry_intoでどういうケースならエラーにして欲しいのか考えればおかしいことに気付く
サードパーティライブラリの学習コストは他の言語に比べると顕著に高いが
基本的な言語機能や標準ライブラリは言うほど高くない
JavaやC#あたりと比べるとむしろ学習コスト低いんじゃないかと思う
908(1): 2024/07/21(日)11:04 ID:xuKRyHnL(1) AAS
>>903
それくらいchatGPTで教えてもらえるだろ
909: 2024/07/21(日)11:14 ID:BMrg5vDt(2/3) AAS
>>908
俺もそう思って試してみたけど駄目だね
エラーの簡単な原因とcollect使えみたいな代替案は出してくるけど
根本的な理解につながる答えを返せないだけでなくいろいろと間違った情報を返してくる
910(2): 2024/07/21(日)11:48 ID:W0nR4Dwz(2/3) AAS
from_iter(array)で済むのに
なぜ配列からHashMapへのFromがあるのか理由はおそらく
配列からmoveするinto_iter()が数年前までなかったためだと思う
今は配列を含めて要素が複数なら→イテレータ利用→FromIteratorと覚えればよいかと
911(2): 2024/07/21(日)11:54 ID:9I2odrUJ(1) AAS
そもそもイテレーターとコンテナの概念を勘違いしてる可能性ありそう
別種のコンテナ同士の変換は (特別な対応がない限り) 直接的には無理で、イテレーターを介して中身の要素を走査すれば渡せるということ
みかん箱を冷蔵庫に変換することはできないけど、箱の中のみかんを1つずつ取り出して、それを冷蔵庫型に纏める (collect) ことはできるような感じ
912: 2024/07/21(日)12:08 ID:QhoywuRk(2/4) AAS
今回は >>910 さんをベストアンサーとさせて頂きます
みなさんご協力ありがとうございました
913: 2024/07/21(日)12:17 ID:rbHgMj6q(1) AAS
>>911
それは単に抽象度の違いであって勘違いでも何でもない
914: 2024/07/21(日)12:17 ID:QhoywuRk(3/4) AAS
>>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);
}
915(1): 2024/07/21(日)12:21 ID:QhoywuRk(4/4) AAS
なぜ Vec から HashMap は from が使えないのか?
の問いに GPT は答えてくれない
916(1): 2024/07/21(日)12:29 ID:+gih9iRs(1) AAS
>>910
順番が逆
arrayにIntoIteratorが実装された方が先で
From array for HashMapのほうが後
917: 2024/07/21(日)12:32 ID:BMrg5vDt(3/3) AAS
>>915
そこはFromのimplがないからと答えてくれる
coherenceの制約を先回りして答えてくれるかどうかは質問次第
918: 2024/07/21(日)13:57 ID:W0nR4Dwz(3/3) AAS
>>916
ありがと
調べたらその順だね
そうなるとFrom<配列>だけを特別に用意した理由は配列が基本型だからだろうか
HashMap::from(array)のコードを見ると
HashMap::from_iter(array)とFromIteratorの実装を呼び出すだけなので
919: 2024/07/21(日)16:06 ID:nMuf3u03(1) AAS
MapやSetのリテラルがないけどリテラルに近い感覚で初期化したい場合の代替策として用意されたのがFromの実装
920(1): 2024/07/21(日)16:20 ID:BJsLblxy(1/3) AAS
_iterの5文字が節約できるメリットだけか
921(1): 2024/07/21(日)16:39 ID:u5tRysNp(1) AAS
>>920
タイプアノテーションの要不要があるのでもっと節約できるよ
922(1): 2024/07/21(日)16:43 ID:BJsLblxy(2/3) AAS
>>921
不要になる例を出して
923(1): 2024/07/21(日)17:05 ID:QAZ3DYjh(1) AAS
FromがあるとIntoが使えるからHashMap返すときとか引数で渡すときに
HashMap::from([..])
の代わりに
[..].into()
で書ける
型を明記するletだと大差ないかも
let map: HashMap<K, V> = [..].into();
let map = HashMap::<K, V>::from([..]);
924: 2024/07/21(日)17:22 ID:BJsLblxy(3/3) AAS
>>923
そこでタイプアノテーションが不要になる例はないよな
関数の引数型か返り型に書いている
into()と書ける件も
collect()と書けるから
FromIteratorに対してFromもあるメリットは3文字節約できるだけか
925: 2024/07/21(日)21:02 ID:eUhj6//q(2/2) AAS
dyn traits以外にinto使うなよ。変換するんだから
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 ID:BUmQiTHC(1) AAS
は?
927(1): 2024/07/21(日)22:10 ID:kEjkNYpd(1/2) AAS
>>922
use std::collections::HashMap;
fn main() {
let xs = [(1, "a"), (2, "b"), (3, "c")];
let map = HashMap::from(xs);
println!("{:?}", map);
}
928(1): 2024/07/21(日)22:23 ID:vNf5wQaP(1) AAS
>>927
HashMap::from_iter(xs)で十分じゃね
929: 2024/07/21(日)22:30 ID:kEjkNYpd(2/2) AAS
>>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
|
930: 2024/07/22(月)12:16 ID:7a9cZObY(1/2) AAS
配列からの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> { ... }
931(1): 2024/07/22(月)12:18 ID:7a9cZObY(2/2) AAS
つまりFromは重いデフォルトハッシャーに固定されてしまっている
FromIteratorを使えば自由に速いものを利用できる
let xxx = HashMap::<_, _, FxHash>::from_iter(array);
932: 2024/07/23(火)01:07 ID:XvQFw5Nb(1/2) AAS
HashMap::from(配列)の場合は
デフォルトハッシャーで困るユースケースは稀だから
APIのエルゴノミクスのために意図的にRandomStateに固定してる
そのおかけでタイプアノテーションなしで書ける
タイプアノテーション無しの場合はデフォルト指定の型を優先的に使うよう
Rustのコンパイラが改良されればこの辺の差はなくなる
933: 2024/07/23(火)01:10 ID:XvQFw5Nb(2/2) AAS
>>931
>let xxx = HashMap::<_, _, FxHash>::from_iter(array);
FxHashのところはFxBuildHasherだね
let xxx = FxHashMap::from_iter(array);と書いたほうがいろいろ親切
親切設計のライブラリなら
let xxx = AHashMap::from(array);
のようにFromIteratorだけでなくFromも使える
934(1): 2024/07/23(火)01:31 ID:Rfg4Mjqa(1) AAS
tupleをiteratorしたいんだが無理?
935(1): 2024/07/23(火)02:50 ID:l+hNtTPE(1) AAS
こういう意味?
let t = ("abcde", "fghijkl", "mno", "pqrstuvw", "xyz");
assert_eq!("abcdefghijklmnopqrstuvwxyz", Into::<[_; 5]>::into(t).into_iter().collect::<String>());
936(1): 2024/07/23(火)09:22 ID:iSDzXJU2(1) AAS
同じ型だけの要素で構成されるtupleならいけそうだけど
色んな型ば混ざってるtupleはエラー出そう
937: 2024/07/23(火)11:25 ID:ijWLrFq+(1) AAS
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}");
}
}
938: 2024/07/23(火)17:24 ID:hqmWVJB3(1) AAS
またFizzBuzzイテレータ書いてる……
939: 2024/07/23(火)21:36 ID:1jhTJKzb(1) AAS
>>936
Haskellだとタプルって構造体代わりだから、色んな型が混ざってる方が普通だけど…。
(ともすれば関数も入れるし。同じ型だけってのはリストのイメージ)
Rustじゃ用途違うん?
940(1): 2024/07/23(火)21:58 ID:joaeWjir(1) AAS
タプルは型の制限なくバラバラでいいよ
今回はそれを>>934「iteratorしたい」なので
同じ型に揃えるためにdynかenumを使う
941: 2024/07/23(火)23:07 ID:tKFzmUCx(1) AAS
ほとんどの言語でオブジェクトを返す時にヒープを使うから
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(1): 2024/07/23(火)23:38 ID:QoNSkCmh(1) AAS
「tupleでイテレートできないの?」という質問に「こういうイテレータなら異なる型を混ぜられるよ」と回答するあたりがいかにもな感じ
率直に「できる/できない」で回答した上で補足として書けばいいのに
943: 2024/07/23(火)23:40 ID:38zrS1+w(1/2) AAS
トレイトオブジェクトをdynと呼ぶのは複オジだけ
944: 2024/07/23(火)23:40 ID:38zrS1+w(2/2) AAS
>>942
それな
945: 2024/07/23(火)23:49 ID:lLea54if(1) AAS
Rust 2018 editionからdyn必須に変わった
946(2): 2024/07/24(水)00:02 ID:QMkBbV1F(1) AAS
できる/できないで言えばできるよ
タプルの要素がすべて同じ型で要素数が12個以内ならFrom/Intoで配列に変換してイテレートする
それ以外ならextension traitで自前のイテレータを返すメソッドをタプルに実装する
他にも方法あるけどこの2つが主
タプルの型・要素数、イテレート時の型を汎用化したい場合はマクロが必須でそこそこめんどくさい
特にヘテロなタプルを汎用的にイテレート用の型に揃えるのはめんどくさい
本当にタプルで管理するのが望ましいのか
タプルで管理しつつイテレータで回すのがベストなのか
まずはよく考えたほうがいいと思う
947: 2024/07/24(水)00:15 ID:sAqPevwn(1) AAS
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),
})
}
948: 2024/07/24(水)00:35 ID:UKniupNy(1/2) AAS
リフレクションのサポートとかにもっと力入れてれば普通にできるんだろうけど、しゃあなし
Rustはそういうの好かない言語だから
949: 警備員[Lv.2][新芽] 2024/07/24(水)00:44 ID:djH/Nw1D(1) AAS
rustって流行るかな
950: 2024/07/24(水)03:12 ID:s3z853Sv(1) AAS
>>940
タプルをイテレーションしたい…。
リストとか、配列みたいに使いってことですよね?
Haskellでは無理ですが、Rustでは可能なのでしょうか?
(構造体代わりと言った通り、構造体をイテレーションしようと思わないですよね?)
Python,RubyのリストとHaskellのそれみたいに、そもそもの意味が違う可能性もありますし…。
951: 2024/07/24(水)03:25 ID:sCVmnNU/(1/4) AAS
>>935
let t = ("abcde", 123, "mno", "pqrstuvw", 456);
for e Into::<[_; 5]>::into(t).into_iter() {
println!("{:?}", e)
}
無理ポorz
952: 2024/07/24(水)03:30 ID:sCVmnNU/(2/4) AAS
>>946
それっぽいクレートがあるけどよう判らん
これはどんな感じ?
外部リンク:crates.io
953: 2024/07/24(水)03:57 ID:yTLgnmif(1) AAS
これは典型的なXY問題だから相手にするだけ無駄
質問者は本当に解決したい元の課題Xを素直に話すべき
自分の思い込みで勝手に判断して進めた二次的な課題Yについて質問しているからそれについては相手にしなくていい
954: 2024/07/24(水)04:42 ID:sCVmnNU/(3/4) AAS
>>946
imple IntoIterator for (&str, u64, &str, &str, u64) {
...
}
で出来るかと思ったけど
this is not defined in the current crate because tuples are always foreign
955: 2024/07/24(水)05:38 ID:U0F2g2Py(1) AAS
dynやenumにしろと本質的なアドバイスをもらえているのに対応しようとしない人
956: 2024/07/24(水)07:25 ID:Py4dd1Kh(1) AAS
たしかにXY問題だな
「異なる型が入り乱れてイテレートしたい」←何のために?
「異なる型が入り乱れてタプルがある」←どうやってそれが出来た?
957: 2024/07/24(水)08:43 ID:NUYI7xpt(1/2) AAS
・タプルは型を混合できる
・タプルはイテレートできない
・異なる型でのイテレートがしたいなら、タプルの代わりに Box<dyn Trait> のような動的型かenum (直和型) の配列を使う
で良いんじゃない?
958: 2024/07/24(水)08:43 ID:sCVmnNU/(4/4) AAS
とりあえず出来ました
struct Hoge<'a> { t: (&str, u64, &str, &str, u64) }
impl<'a> IntoIterator for Hoge<'a> {
type Item = Fuga<'a>;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
vec![
Fuga::from(self.t.0),
Fuga::from(self.t.1),
Fuga::from(self.t.2),
Fuga::from(self.t.3),
Fuga::from(self.t.4),
].into_iter()
}
}
みなさんありがとうございました
959(1): 2024/07/24(水)08:50 ID:NUYI7xpt(2/2) AAS
XY問題だとか言うけど、上のFizzBuzイテレーターなんかはXとYのどちらとも関係ないでしょ
既にあるデータに対してイテレートする方法でなく、FizzBuzを0から生成するだけだから
それをしつこく何度も書くあたりが本物
960: 2024/07/24(水)09:24 ID:eaHzhPzb(1) AAS
>>959
それな
961: 2024/07/24(水)09:30 ID:+W2StRcH(1) AAS
意味のないFizzBuzzを散々書いておいて答えられなくなったら急に質問者を攻撃する複オジくん草
962: 2024/07/24(水)12:35 ID:qFVR7Ywl(1/3) AAS
必要な個数のタプルを配列に変換するコードでいいんじゃないかな
これは長さ自由に機械的にマクロで生成できそう
struct Wrapper<A, B, C, D, E>((A, B, C, D, E));
impl<A, B, C, D, E> From<Wrapper<A, B, C, D, E>> for [Tx; 5]
where
Tx: From<A> + From<B> + From<C> + From<D> + From<E
{
fn from(x: Wrapper<A, B, C, D, E>) -> Self {
[Tx::from(x.0.0), Tx::from(x.0.1), Tx::from(x.0.2), Tx::from(x.0.3), Tx::from(x.0.4)]
}
}
impl<A, B, C, D, E> IntoIterator for Wrapper<A, B, C, D, E>
where
Tx: From<A> + From<B> + From<C> + From<D> + From<E
{
type Item = Tx;
type IntoIter = std::array::IntoIter<Self::Item, 5>;
fn into_iter(self) -> Self::IntoIter {
let x: [Self::Item; 5] = self.into();
x.into_iter()
}
}
963: 2024/07/24(水)12:36 ID:qFVR7Ywl(2/3) AAS
AA省
964: 2024/07/24(水)12:38 ID:qFVR7Ywl(3/3) AAS
そうするとタプルの中の型の順番は任意でよくて
タプルをラッパーにかませるだけで利用できるよ
fn main() {
let tuple = ("abcde", 123, "nop", 0.456, 789);
for x in Wrapper(tuple) {
println!("{x}");
}
for (i, x) in Wrapper((-1, "pi", 3, 3.14159, "END")).into_iter().enumerate() {
println!("{i}: {x}");
}
}
965: 2024/07/24(水)12:43 ID:mjGiit/q(1) AAS
効いてる効いてるw
966: 2024/07/24(水)12:49 ID:TJmYfYAi(1) AAS
「XY問題だから相手にするだけ無駄」と言い放っておいてからの〜〜
967: 2024/07/24(水)17:04 ID:1Kw3Uuff(1) AAS
もっと建設的な話題はないの?
968: 2024/07/24(水)19:14 ID:UKniupNy(2/2) AAS
5chより建設的なコミュニティを列挙し移住を検討するのが目下最も建設的な話題である
969: 2024/07/24(水)21:00 ID:bzm5y73f(1) AAS
最近出た便利クレートの話とかすれば良いんじゃね?
970: 2024/07/24(水)22:25 ID:mF9Tvkg9(1) AAS
ベストな日付処理クレートについて議論しよう
971: 2024/07/25(木)08:45 ID:q/t9CUhu(1) AAS
おすすめクレートの話はしてほしいな~
972: 2024/07/25(木)10:09 ID:P+cFrEvf(1) AAS
クレートの話をしてくれー、と
973(1): 2024/07/25(木)22:41 ID:zdgCFOr2(1/2) AAS
クレートではないけれど今日リリースのRust 1.80でLazyCell, LazyLockが安定版に入ったよ
グローバルな変数を外部クレート無しで書きやすくなる
974(1): 2024/07/25(木)22:49 ID:9YYk7vP+(1) AAS
>>973
それ、OnceCell使ってたコードは全部置き換えた方がいい奴?
975: 2024/07/25(木)23:18 ID:zdgCFOr2(2/2) AAS
>>974
自分はそれを言えるほど詳しくないけど、必ずしも必要ではないと思う
依存クレートを減らせる点で嬉しいし、今から書くコードでは新しいものにして良いと思うけど、今使ってるものをすぐに置き換える必要があるとまでは思わない
特にライブラリを作ってる場合は、rustcを今日リリースされたばかりの最新バージョンに上げないとライブラリをビルドできなくなるということなので、もう少し待った方が良いかもしれない
976: 2024/07/26(金)00:25 ID:/65SSmn2(1/2) AAS
OnceLockからLazyLockへ移行すると
変数宣言と初期化関数が離れていた可読性の問題が解決するとともに
例えばget_or_initを一箇所にするために一つ関数を用意したりするなどしていた手間も省けるようになるね
そして何よりも最大のメリットはDerefによりアクセスできる利便性
977: 2024/07/26(金)23:32 ID:/65SSmn2(2/2) AAS
とりあえず定番のこのあたりを置き換えた
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new("...").unwrap());
static SE: LazyLock<Selector> = LazyLock::new(|| Selector::parse("...").unwrap());
978(1): 2024/07/27(土)11:02 ID:WfV9QQMJ(1) AAS
LazyLockよさそうね
979(3): 2024/07/27(土)18:38 ID:U5WpGSyZ(1/2) AAS
俺の今日のハマりポイントを紹介
bindgenにC++のコンストラクタを作らせると、データが壊れる
よく調べたら公式ドキュメントのConstructor semanticsに書いてあった
外部リンク[html]:rust-lang.github.io
コンストラクタを抜けたとき、C++とちがってRustは値をムーブしちゃうので
struct内部を参照したポインタが変なところを参照してバグる
980(2): 2024/07/27(土)19:30 ID:s18eFGvS(1) AAS
C++も部分的に使えるとはいえ、FFIするならCのAPIにしておく方が無難な気はする
981: 2024/07/27(土)20:04 ID:U5WpGSyZ(2/2) AAS
>>980
bindgenはFirefoxがプロダクトでたくさん使ってるって聞いて、いけると思ったんだ
Firefoxは大半がC++だから
982: 2024/07/28(日)15:27 ID:v6kdbv5j(1/2) AAS
>>978
LazyLockさようなら
に観えた
983: 2024/07/28(日)15:29 ID:v6kdbv5j(2/2) AAS
>>979
RustとC++は相性最悪
RustとCは相性良いバッチリ
984(1): 2024/07/30(火)01:24 ID:xgbf/AIH(1) AAS
>>979
この件って、RustはC++と比べて無駄にムーブするから遅いってこと?
985(3): 2024/07/30(火)06:04 ID:RHAjweCG(1) AAS
無駄な移動は消える
cargo asmで生成コードを見ることでそれを確認できる
移動前と移動後のアドレスを表示させて最適化を阻害することで元は別々となる例も確認できる
986(1): 2024/07/30(火)12:06 ID:tiWzrJ23(1) AAS
>>984
>コンストラクタを抜けたとき、C++とちがってRustは値をムーブしちゃうので
>struct内部を参照したポインタが変なところを参照してバグる
って書いてるのに、読解力無い人?
987(1): 2024/07/30(火)19:02 ID:dzXOiSL/(1) AAS
>>985
移動じゃなくてムーブね
ここまでのレスで使われてる述語を踏襲すればいいよ
988(1): 2024/07/30(火)20:13 ID:VUdF4pDl(1) AAS
>>985
最適化のかかり具合でバグが消えたり現れたりする嫌なパターンだな
989(1): 2024/07/30(火)20:41 ID:+5mpqNgW(1) AAS
>>986
Rustを使えばそんなバグは起きない
参照のライフタイムは参照先より長くなることがコンパイル時点で保証される
>>988
Rustならばそこでバグは起きようがない
990(1): 2024/07/30(火)22:41 ID:GjQxUZ/0(1) AAS
>>989
本人じゃないのに出しゃばらせて頂きますが…。
Rust単体じゃなくて、C++との相性問題ですよ。相性最悪って書いてるんだから。
起きようがないじゃなくて、実際に起きてるらしいじゃないですか。
最適化で治るのなら大したことじゃなくても、デバッグ時にハマるの確実な類のバグ。
将来的に全部Rustで書けば起きないような問題も、過渡期の今は良く起きます。
「Rustを使えば」「Rustなら」。
そうでしょうけど、実際問題ライブラリがなければ既存のC/C++ライブラリ使う場面は多々あるでしょう。
(枯れたライブラリならなおさら)
これはRustに限らず、後続の言語全てが抱えている問題です。
991: 2024/07/30(火)22:49 ID:MqLM+D1V(1/3) AAS
最適化じゃなくて単に移動の問題
Box::newで要素を直接ヒープに作れない (いちどスタックに作られてからコピーされる) のと同じで、コンストラクタを抜ける前に構造体が maybeuninit::assume_init で移動する
その上で構造体のアドレスがC++のメソッドにthisポインタとして渡される際に問題を引き起こす、というように思える
だとすると最適化の有無は関係なく起こる気がする
ついでにいえば >>987 もあまり意味のない発言で、移動はムーブの訳語でもある (例えばC++の仕様の訳語に移動コンストラクタという表現がある) し、そもそもこの問題はムーブセマンティクスによるものでもない
これはStringやVecが持つリソースを所有権ごと移動することで効率的に別の変数に割り当てるもので、構造体のアドレスのようなローレベルなものとは違うかと
992: 2024/07/30(火)22:59 ID:MqLM+D1V(2/3) AAS
移動とムーブが仕様として別物だというなら、移動は英語でどう表現されてるんだ?
993: 2024/07/30(火)23:00 ID:L/ylOhaJ(1) AAS
>>990
それはRust単体では全く発生しない問題だね
C++とRustを併用する時にRustの知識を持たない人がハマるという話
FFI部分は両者の概念と挙動の違いの知識を持った人が作るべきだね
994(1): 2024/07/30(火)23:13 ID:EnloT7kO(1) AAS
>>979
>>値をムーブしちゃうのでstruct内部を参照したポインタが変なところを参照してバグる
Rustでそのような自己参照はムーブでライフタイム切れとなるためバグは発生しなくて
自己参照を保ちたいならば値がムーブしなければよくて
値がムーブしないためにはスタック上でそのまま使うかヒープ上に確保して使えばよくて
それを保証するためにRustではPinという枠組みがあって安全に取り扱えるようになってるよ
995: 2024/07/30(火)23:19 ID:MqLM+D1V(3/3) AAS
>>994
bindgenの作者に言ってあげればいいと思うよ
ついでに改善したコードをPRしてコントリビュートしてみてはどうだろう
使用者のミスを擦るよりもずっと有意義なはず
996: 2024/07/30(火)23:48 ID:dZ3/RfBM(1) AAS
同意
997: 2024/07/31(水)11:32 ID:yHR2oE13(1/4) AAS
結合が密過ぎないかこの言語
998: 2024/07/31(水)11:35 ID:yHR2oE13(2/4) AAS
>将来的に全部Rustで書けば起きないような問題
さっさと仕事しろおまいらってことですね判ります
999: 2024/07/31(水)12:10 ID:yHR2oE13(3/4) AAS
>>985
Pin
1000: 2024/07/31(水)12:10 ID:yHR2oE13(4/4) AAS
Pin<Arc<T>>
1001(1): 1001 ID:Thread(1/2) AAS
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 65日 5時間 29分 33秒
1002(1): 1002 ID:Thread(2/2) AAS
5ちゃんねるの運営はUPLIFT会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《UPLIFT会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
4 USD/mon. から匿名でご購入いただけます。
▼ UPLIFT会員登録はこちら ▼
外部リンク:uplift.5ch.net
▼ UPLIFTログインはこちら ▼
2ch板:login
上下前次1-新書関写板覧索設栞歴
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.027s