Rust part27 (411レス)
Rust part27 http://mevius.5ch.net/test/read.cgi/tech/1733146370/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
62: デフォルトの名無しさん [] 2024/12/06(金) 12:07:14.30 ID:tRnxKL09 すいません*つけわすれました http://mevius.5ch.net/test/read.cgi/tech/1733146370/62
63: デフォルトの名無しさん [] 2024/12/06(金) 12:08:12.03 ID:tRnxKL09 >>60 終了条件は25です http://mevius.5ch.net/test/read.cgi/tech/1733146370/63
64: デフォルトの名無しさん [sage] 2024/12/06(金) 12:19:03.26 ID:B3lagOoh 結局毎回同じ参照返すならイテレータじゃなくてよくね http://mevius.5ch.net/test/read.cgi/tech/1733146370/64
65: デフォルトの名無しさん [sage] 2024/12/06(金) 12:49:52.12 ID:B2jbh63z 自分の可変参照を返したいならGATでこうする use lending_iterator::prelude::*; fn main() { let mut v: Vec<String> = ["a", "b", "c", "d", "e"].into_iter().map(str::to_string).collect(); my_iter_mut(&mut v) .skip(1) .take(3) .for_each(|s| s.push('x')); assert_eq!(v, ["a", "bx", "cx", "dx", "e"]); } fn my_iter_mut<'a, T>(slice: &'a mut [T]) -> MyIterMut<'a, T> { MyIterMut { slice, index: 0 } } struct MyIterMut<'a, T> { slice: &'a mut [T], index: usize, } #[gat] impl<'a, T> LendingIterator for MyIterMut<'a, T> { type Item<'next> where Self : 'next = &'next mut T; fn next(self: &'_ mut MyIterMut<'a, T>) -> Option<Item<'_, Self>> { if self.index < self.slice.len() { self.index += 1; Some(&mut self.slice[self.index - 1]) } else { None } } } http://mevius.5ch.net/test/read.cgi/tech/1733146370/65
66: デフォルトの名無しさん [sage] 2024/12/06(金) 17:58:05.19 ID:B2jbh63z >>65 自己レス 即興で作って冗長な表記があったため next()関数はこれで fn next(&mut self) -> Option<Item<'_, Self>> { (self.index < self.slice.len()).then(|| { let nth = &mut self.slice[self.index]; self.index += 1; nth }) } http://mevius.5ch.net/test/read.cgi/tech/1733146370/66
67: デフォルトの名無しさん [sage] 2024/12/06(金) 18:45:17.16 ID:OtZyNvR4 >>61 next()で返された不変参照r1(&i32)が生きてる間に次のnext()が呼ばれたら r1の参照先の値が変わることになるからこの形はIteratorだと実現できないな 同じ値に対する&Tと&mut Tが共存できないルールに引っかかる next()の戻り値にIt自体のライフタイム(&'b mut selfの'b)を含めて 戻り値の参照が存在してる間は次のnext()を呼べない形にしないといけないけど Iteratorはそういう制限を想定してない http://mevius.5ch.net/test/read.cgi/tech/1733146370/67
68: デフォルトの名無しさん [sage] 2024/12/07(土) 00:37:25.75 ID:MlZHBv1+ Vecなどを作れて逆順にもできるイテレータとは性質が異なる 異なるものを、どっちも同じだと頑なに主張し続ける必要はない気がする http://mevius.5ch.net/test/read.cgi/tech/1733146370/68
69: デフォルトの名無しさん [sage] 2024/12/07(土) 02:06:00.13 ID:TKfUhpHo 67は一般的なイテレータの概念じゃなくstd::iter::Iteratorの話 このtraitを実装すると例えばIterator::max()も自動的に使えるようになるけど この実装はSelf::Itemの暫定の最大値を保持しながら次のnextを呼ぶ必要がある 前の値を解放しないと次のnextを使えない状態だと std::iter::Iteratorが使用者側に保証してる条件を満たせないし 安全なコードの範囲でimpl Iteratorのコンパイルも通せない 自前のIteratorトレイトを用意してもいいけど それだとstd::iter::Iteratorが要求される処理には使えなくなる http://mevius.5ch.net/test/read.cgi/tech/1733146370/69
70: デフォルトの名無しさん [sage] 2024/12/07(土) 08:46:15.51 ID:4WGAo47f >>68 Vecを作れるのも逆順も全て別の話 それぞれ別の要件を備えていないと一般的なイテレータではどちらも不可能 例えばイテレータ「1..」はVecを作れない&逆順に呼ぶのも無理 std::iter::repeat(1)はVecを作れないがDoubleEndedIteratorを実装しているのでメソッドrev()が使えて逆順に呼べる! 自己可変参照を返す>>65のMyIterMutはスライス&mut [T]を内部に持っているため逆順呼び出しrev()メソッドの実装が可能 http://mevius.5ch.net/test/read.cgi/tech/1733146370/70
71: デフォルトの名無しさん [sage] 2024/12/07(土) 09:01:24.50 ID:4WGAo47f >>69 そのmax()は自動的に全てのイテレータに使えるわけではない Self::Itemがstd::cmp::Ordを実装している時のみ使える 前の値を保持したままにできるか否かの性質についてもmarker traitを用意することで同じ枠組みに組み込めた可能性がある それを出来ていないのがstd::iter::Iteratorの欠陥なので他を併用するのがRustでは当たり前になっている http://mevius.5ch.net/test/read.cgi/tech/1733146370/71
72: デフォルトの名無しさん [sage] 2024/12/07(土) 09:28:12.85 ID:4WGAo47f イテレータの前の値を保持できるか否かのどちらが優れているかといえば より効率的な機能を提供できる点で「前の値を保持できない」方が優れた機能を提供できる 例えばstd::io::BufReadのlines()を考えてみよう 毎回新たなStringを返してくるので前の値を保持できる仕様となっている しかしlines()の利用で前の値なんて不要なことも多いからその観点からは無駄な仕様ともいえる 一方で「前の値を保持できない」性質にも対応出来ていたとしたら同じStringを使い回すことが出来て明らかに効率が良い このような例は多数あり自己参照返しイテレータが別途必要とされて使われている理由である http://mevius.5ch.net/test/read.cgi/tech/1733146370/72
73: デフォルトの名無しさん [sage] 2024/12/07(土) 12:31:06.78 ID:MlZHBv1+ >>70 長さが有限でも実行時にメモリが足りなければVecもreverseもないけど 「実行時に」という要件は備えなくて良いというルールがあるんだよね? http://mevius.5ch.net/test/read.cgi/tech/1733146370/73
74: デフォルトの名無しさん [sage] 2024/12/07(土) 12:55:43.06 ID:TKfUhpHo 61(初心者)が実現できないimpl Iteratorで詰まってるんだから できない理由を分かってもらうのが優先でしょ イテレータの優劣とか代替案はその後でいい http://mevius.5ch.net/test/read.cgi/tech/1733146370/74
75: デフォルトの名無しさん [sage] 2024/12/07(土) 13:24:25.81 ID:4WGAo47f >>73 rev()メソッドのtrait DoubleEndedIteratorはゼロコスト抽象化 逆順に並べ替えることはしないのでそのためのメモリは必要ない 既にある任意の構造を後ろからたどる、あるいは、後ろから計算するだけ http://mevius.5ch.net/test/read.cgi/tech/1733146370/75
76: デフォルトの名無しさん [sage] 2024/12/07(土) 13:35:30.31 ID:4WGAo47f >>74 それならば別の条件が必要となるIterator::max()を事例に出すのはよろしくないかな 説明するためには単純にこれだけでいいよ let first = iter.next(); let second = iter.next(); println!("{first:?} {second:?}"); http://mevius.5ch.net/test/read.cgi/tech/1733146370/76
77: デフォルトの名無しさん [sage] 2024/12/07(土) 14:11:16.76 ID:TKfUhpHo >>76 next2回呼ぶだけだとstd::iter::Iteratorと関係なくなるだろ 自分がそういう使い方をしなければ問題ないってなるだけ maxはstd::iter::Iteratorの実装に求められる条件の分かりやすい例として挙げた 別の条件まで気にするならmax_byでもいいけどそれはそれで初心者には余計なノイズが増える http://mevius.5ch.net/test/read.cgi/tech/1733146370/77
78: デフォルトの名無しさん [sage] 2024/12/07(土) 14:52:07.98 ID:MlZHBv1+ コピーもcloneもできないデータの存在自体がノイズだね 本当はcloneできるんだけどゼロコストではできないとか言ってるのもノイズだ http://mevius.5ch.net/test/read.cgi/tech/1733146370/78
79: デフォルトの名無しさん [sage] 2024/12/07(土) 15:42:48.47 ID:YxUwNEYs 結局>>53は何がしたかったのか http://mevius.5ch.net/test/read.cgi/tech/1733146370/79
80: デフォルトの名無しさん [sage] 2024/12/07(土) 16:58:02.14 ID:ikP3bVWr >>67 stdのIterator::nextの&mut selfのライフタイムはnextメソッドを抜けるところまで (次のnextが呼ばれるまで生きてない) つまりstdのIteratorでは&mut selfのライフタイムに依存するような参照を返すことはできないということ そういう参照を返したいならlending iterator 逆に言えば&mut selfのライフタイムに依存しない参照であればstdのIteratorでも返せるということ http://mevius.5ch.net/test/read.cgi/tech/1733146370/80
81: デフォルトの名無しさん [sage] 2024/12/07(土) 17:27:34.95 ID:4WGAo47f >>77 max_byも同じ Ord実装型そのものかOrd実装型に変換してOrd::cmp()できる時のみ利用できる それらを持ち出さなくてもSelf::Itemの条件なくcollect()すなわち収納型へのFromIteratorが適用される つまりfirst要素とsecond要素が同時に存在することになると矛盾の説明で十分となる そのため自己参照を返すイテレータはstd::iter::Iteratorがカバーする範囲になく別途必要となる話をしてきた http://mevius.5ch.net/test/read.cgi/tech/1733146370/81
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
あと 330 レスあります
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.912s*