公式
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 part26
https://mevius.5ch.net/test/read.cgi/tech/1726838318/
ワッチョイスレ
プログラミング言語 Rust 4【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1514107621/
Rust part27
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2024/12/02(月) 22:32:50.31ID:D+1pIyvG2024/12/07(土) 14:11:16.76ID:TKfUhpHo
>>76
next2回呼ぶだけだとstd::iter::Iteratorと関係なくなるだろ
自分がそういう使い方をしなければ問題ないってなるだけ
maxはstd::iter::Iteratorの実装に求められる条件の分かりやすい例として挙げた
別の条件まで気にするならmax_byでもいいけどそれはそれで初心者には余計なノイズが増える
next2回呼ぶだけだとstd::iter::Iteratorと関係なくなるだろ
自分がそういう使い方をしなければ問題ないってなるだけ
maxはstd::iter::Iteratorの実装に求められる条件の分かりやすい例として挙げた
別の条件まで気にするならmax_byでもいいけどそれはそれで初心者には余計なノイズが増える
2024/12/07(土) 14:52:07.98ID:MlZHBv1+
コピーもcloneもできないデータの存在自体がノイズだね
本当はcloneできるんだけどゼロコストではできないとか言ってるのもノイズだ
本当はcloneできるんだけどゼロコストではできないとか言ってるのもノイズだ
2024/12/07(土) 15:42:48.47ID:YxUwNEYs
結局>>53は何がしたかったのか
2024/12/07(土) 16:58:02.14ID:ikP3bVWr
>>67
stdのIterator::nextの&mut selfのライフタイムはnextメソッドを抜けるところまで
(次のnextが呼ばれるまで生きてない)
つまりstdのIteratorでは&mut selfのライフタイムに依存するような参照を返すことはできないということ
そういう参照を返したいならlending iterator
逆に言えば&mut selfのライフタイムに依存しない参照であればstdのIteratorでも返せるということ
stdのIterator::nextの&mut selfのライフタイムはnextメソッドを抜けるところまで
(次のnextが呼ばれるまで生きてない)
つまりstdのIteratorでは&mut selfのライフタイムに依存するような参照を返すことはできないということ
そういう参照を返したいならlending iterator
逆に言えば&mut selfのライフタイムに依存しない参照であればstdのIteratorでも返せるということ
2024/12/07(土) 17:27:34.95ID:4WGAo47f
>>77
max_byも同じ
Ord実装型そのものかOrd実装型に変換してOrd::cmp()できる時のみ利用できる
それらを持ち出さなくてもSelf::Itemの条件なくcollect()すなわち収納型へのFromIteratorが適用される
つまりfirst要素とsecond要素が同時に存在することになると矛盾の説明で十分となる
そのため自己参照を返すイテレータはstd::iter::Iteratorがカバーする範囲になく別途必要となる話をしてきた
max_byも同じ
Ord実装型そのものかOrd実装型に変換してOrd::cmp()できる時のみ利用できる
それらを持ち出さなくてもSelf::Itemの条件なくcollect()すなわち収納型へのFromIteratorが適用される
つまりfirst要素とsecond要素が同時に存在することになると矛盾の説明で十分となる
そのため自己参照を返すイテレータはstd::iter::Iteratorがカバーする範囲になく別途必要となる話をしてきた
2024/12/07(土) 17:32:25.17ID:4WGAo47f
>>78
イテレータが返すのはデータ値自体とは限らず参照も返す
特に今回の質問者が返したい可変参照は明確に!Cloneが定義されていてもちろん!Copyでもある
それでも可変参照をイテレータが返すことができてVecへ収容することも可能なのはCloneもコピーも行われないためだ
さらにそれらと全く独立した話としてイテレータ自体への参照/可変参照を返す場合はstd::iter::Iteratorで扱えないためLendingIteratorを使うという話が本題
イテレータが返すのはデータ値自体とは限らず参照も返す
特に今回の質問者が返したい可変参照は明確に!Cloneが定義されていてもちろん!Copyでもある
それでも可変参照をイテレータが返すことができてVecへ収容することも可能なのはCloneもコピーも行われないためだ
さらにそれらと全く独立した話としてイテレータ自体への参照/可変参照を返す場合はstd::iter::Iteratorで扱えないためLendingIteratorを使うという話が本題
2024/12/07(土) 18:53:41.33ID:MlZHBv1+
そんなに移動がしたいならこれでいい
first = into_next(iter); // iterはもう値を所有しない
second = into_next(first) // firstはもう値を所有しない
first = into_next(iter); // iterはもう値を所有しない
second = into_next(first) // firstはもう値を所有しない
2024/12/07(土) 19:21:07.13ID:8M4lSePd
>>83
それによって新たにできるようになることや新たに生じるメリットは何?
それによって新たにできるようになることや新たに生じるメリットは何?
2024/12/07(土) 21:52:51.51ID:MlZHBv1+
C++でもRustでも変わらないメリットはcloneとdropをしなくてすむことだが
そういえば、Rust固有のメリットは'aが出てこないことと
'staticも出てこないことだな
そういえば、Rust固有のメリットは'aが出てこないことと
'staticも出てこないことだな
2024/12/08(日) 15:04:28.36ID:vgRddWB1
全然話変わるんだけどPinky Crush新曲のlowercase lifetimeってRust関係あるのかな
87デフォルトの名無しさん
2024/12/08(日) 22:46:56.54ID:y6R7+MXT >>61
mutでないiterも出来なくて困ってるとのことなので
スライスのiter()と同じものがLendingIteratorを使わずに書けるよ
struct MyIter<'a, T>(&'a [T]);
fn my_iter<'a, T>(slice: &'a [T]) -> MyIter<'a, T> {
MyIter(slice)
}
impl<'a, T> std::iter::Iterator for MyIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if let [first, rest @ ..] = self.0 {
self.0 = rest;
Some(first)
} else {
None
}
}
}
fn main() {
let a = ["foo", "bar"];
let mut iter = my_iter(&a);
assert_eq!(iter.next(), Some(&"foo"));
assert_eq!(iter.next(), Some(&"bar"));
assert_eq!(iter.next(), None);
}
mutでないiterも出来なくて困ってるとのことなので
スライスのiter()と同じものがLendingIteratorを使わずに書けるよ
struct MyIter<'a, T>(&'a [T]);
fn my_iter<'a, T>(slice: &'a [T]) -> MyIter<'a, T> {
MyIter(slice)
}
impl<'a, T> std::iter::Iterator for MyIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if let [first, rest @ ..] = self.0 {
self.0 = rest;
Some(first)
} else {
None
}
}
}
fn main() {
let a = ["foo", "bar"];
let mut iter = my_iter(&a);
assert_eq!(iter.next(), Some(&"foo"));
assert_eq!(iter.next(), Some(&"bar"));
assert_eq!(iter.next(), None);
}
2024/12/09(月) 08:04:13.18ID:kf5GINDJ
組み込みFW屋さんなんだけどRustやってみようかな…
組み込み屋視点でRustはC++の何を解決してると思う?
組み込み屋なんて古いシステムばかりだからすぐに取って代わることは無いとは思うけど
年々複雑な製品を求められるから選択肢としては持っておきたい
組み込み屋視点でRustはC++の何を解決してると思う?
組み込み屋なんて古いシステムばかりだからすぐに取って代わることは無いとは思うけど
年々複雑な製品を求められるから選択肢としては持っておきたい
2024/12/09(月) 09:11:23.41ID:bWuDC7pJ
zulip行けば?
ここにはカスしかおらん
ここにはカスしかおらん
2024/12/09(月) 09:29:03.77ID:1L49Pn1/
>>88
ダングリング参照を発見出来るだけ……とは言えそれが重要ではあるのだけど。
C++ は結局は人が気を付けなきゃならないことだらけで、複雑になると手におえない。
知ってることでも複雑に絡み合った状況では間違う。
C++ よりは機械的に検証可能な範囲を広げてるだけでもありがたいものだよ。
ダングリング参照を発見出来るだけ……とは言えそれが重要ではあるのだけど。
C++ は結局は人が気を付けなきゃならないことだらけで、複雑になると手におえない。
知ってることでも複雑に絡み合った状況では間違う。
C++ よりは機械的に検証可能な範囲を広げてるだけでもありがたいものだよ。
2024/12/09(月) 09:59:55.51ID:kf5GINDJ
2024/12/09(月) 10:35:05.93ID:URePCLgA
ビット幅気にするようなケースだと
数値型の暗黙の型変換がないとか演算時のオーバーフローの扱いを明示的に書けるとかが結構ありがたい
数値型の暗黙の型変換がないとか演算時のオーバーフローの扱いを明示的に書けるとかが結構ありがたい
93デフォルトの名無しさん
2024/12/09(月) 13:24:01.49ID:wWCmXoxS 科学 + 5ch
【AI】AIはわずか2時間の対話で人間の性格をコピーできる [すらいむ★]
https://egg.5ch.net/test/read.cgi/scienceplus/1733576027/
コメントに面白いことが書かれている
【AI】AIはわずか2時間の対話で人間の性格をコピーできる [すらいむ★]
https://egg.5ch.net/test/read.cgi/scienceplus/1733576027/
コメントに面白いことが書かれている
94デフォルトの名無しさん
2024/12/09(月) 13:32:22.31ID:elhM3R9g95デフォルトの名無しさん
2024/12/09(月) 13:59:10.18ID:uh4vUAM3 釣れますか?
2024/12/09(月) 20:25:44.95ID:MZPPSq7i
struct RefMutex<'a, T>(&'a Mutex<T>);
impl<'a, T> Iterator for RefMutex<'a, T> {
type Item = std::sync::MutexGuard<'a, T>;
//略
}
try_lockが失敗したらループが止まります
マルチスレッドならランダムに止まります 知らんけど
impl<'a, T> Iterator for RefMutex<'a, T> {
type Item = std::sync::MutexGuard<'a, T>;
//略
}
try_lockが失敗したらループが止まります
マルチスレッドならランダムに止まります 知らんけど
2024/12/09(月) 20:57:28.00ID:bWuDC7pJ
FnMut() -> Option<T>っぽいあらゆる処理を全部Iterator化しようという気概を感じるな
近寄らんとこ
近寄らんとこ
2024/12/09(月) 22:22:52.93ID:FjJr0oeZ
イテレータが勝手にループすることはない
ループするよう別途コードを書かなければならない
Option<T>を返す関数をfとすると
while let Some(x) = f() { ... } で十分である
つまりイテレータ実装する意味がない
イテレータメソッドに繋げたい!という反論もあろう
それなら std::iter::from_fn(f) で十分である
ループするよう別途コードを書かなければならない
Option<T>を返す関数をfとすると
while let Some(x) = f() { ... } で十分である
つまりイテレータ実装する意味がない
イテレータメソッドに繋げたい!という反論もあろう
それなら std::iter::from_fn(f) で十分である
2024/12/10(火) 01:03:26.70ID:EhFU+3MS
Iteratorの話は、lifetimeの棍棒で殴られたという文脈で出てきただけだな
構造体のメンバーが&'a Mutex<T>なら
reborrowではなくmoveで取得した値に対しderef_mutが使える
moveなら殴られない
構造体のメンバーが&'a Mutex<T>なら
reborrowではなくmoveで取得した値に対しderef_mutが使える
moveなら殴られない
100デフォルトの名無しさん
2024/12/10(火) 12:58:54.26ID:maUGvQsb101デフォルトの名無しさん
2024/12/11(水) 12:00:23.09ID:FLapvbLS これはポリシーというか戦略が違ってて、「今より少しでも改善するなら採用」だからじゃないかと
従来型の「最低限のクオリティに達するまではreject」へのアンチテーゼでもあるから
そして(文句あるかもしれんが)crates開発者は元々のエンジニアの質がそこそこ高かったからそれでも何とかなったものの、
同じ事をGitでやったからあの「ぼくがおもいついたすごいcrates」の山になったのだと思う
交通整理すらやる気無かったわけだ
とはいえ、「使われなくなったcratesは、いつしか動かなくなった事すら認識されなくなり、死んでいく」という、
Gitコマンド内でのライフゲームをやるつもりなら、ありなんだろうさ
従来型の「最低限のクオリティに達するまではreject」へのアンチテーゼでもあるから
そして(文句あるかもしれんが)crates開発者は元々のエンジニアの質がそこそこ高かったからそれでも何とかなったものの、
同じ事をGitでやったからあの「ぼくがおもいついたすごいcrates」の山になったのだと思う
交通整理すらやる気無かったわけだ
とはいえ、「使われなくなったcratesは、いつしか動かなくなった事すら認識されなくなり、死んでいく」という、
Gitコマンド内でのライフゲームをやるつもりなら、ありなんだろうさ
102デフォルトの名無しさん
2024/12/12(木) 23:08:54.89ID:qS1eLhOO C/C++からRustへ:Googleが示すファームウェア進化の道筋
https://xenospectrum.com/google-revamps-firmware-with-rust/
https://xenospectrum.com/google-revamps-firmware-with-rust/
103デフォルトの名無しさん
2024/12/14(土) 11:03:48.81ID:mSSbYcoF 読み終わった
>>102
具体的なアプローチは以下の通りである:
(1) 段階的なRust導入:
略
(2) 既存のCコードベースとの統合:
略
(3) ベアメタル環境への対応:
略
(4) ビルド最適化とパフォーマンスの考慮:
略
>>102
具体的なアプローチは以下の通りである:
(1) 段階的なRust導入:
略
(2) 既存のCコードベースとの統合:
略
(3) ベアメタル環境への対応:
略
(4) ビルド最適化とパフォーマンスの考慮:
略
104デフォルトの名無しさん
2024/12/15(日) 23:03:38.24ID:ehGoRf8d Rustで連番IDを発行する関数はこれでいい?
fn new_id() -> Option<usize> {
thread_local! {
static ID: Cell<usize> = Cell::new(0);
}
ID.get().checked_add(1).inspect(|&new_id| ID.set(new_id))
}
fn new_id() -> Option<usize> {
thread_local! {
static ID: Cell<usize> = Cell::new(0);
}
ID.get().checked_add(1).inspect(|&new_id| ID.set(new_id))
}
105デフォルトの名無しさん
2024/12/15(日) 23:37:25.98ID:YS3isBj8 mutableなRange(0..)をIteratorとして使う小技があるけど
オーバーフローは意識したことないな
fn new_id() -> Option<usize> {
use std::cell::RefCell;
use std::ops::RangeInclusive;
thread_local! {
static ID: RefCell<RangeInclusive<usize>> = RefCell::new(0..=usize::MAX);
}
ID.with_borrow_mut(|ids| ids.next())
}
オーバーフローは意識したことないな
fn new_id() -> Option<usize> {
use std::cell::RefCell;
use std::ops::RangeInclusive;
thread_local! {
static ID: RefCell<RangeInclusive<usize>> = RefCell::new(0..=usize::MAX);
}
ID.with_borrow_mut(|ids| ids.next())
}
106デフォルトの名無しさん
2024/12/15(日) 23:49:49.46ID:ehGoRf8d >>105
Cellで済むところがRefCellになってしまってメリットがよくわからないです
Cellで済むところがRefCellになってしまってメリットがよくわからないです
107デフォルトの名無しさん
2024/12/16(月) 00:17:21.21ID:QlO1DQXb 合わせたつもりだったけど104の実装だと最初のidは1か
108デフォルトの名無しさん
2024/12/16(月) 00:32:53.11ID:QlO1DQXb 0から開始できる形でCellにこだわるなら↓みたいな実装もありそう
fn new_id() -> Option<usize> {
thread_local! {
static ID:Cell<Option<usize>> = Cell::new(Some(1)); // ←0開始ならSome(0)
}
ID.replace(ID.get().map(|i| i.checked_add(1)).flatten())
}
fn new_id() -> Option<usize> {
thread_local! {
static ID:Cell<Option<usize>> = Cell::new(Some(1)); // ←0開始ならSome(0)
}
ID.replace(ID.get().map(|i| i.checked_add(1)).flatten())
}
109デフォルトの名無しさん
2024/12/16(月) 01:08:38.61ID:KPayFncJ スレッド単位の連番て何やの?
110デフォルトの名無しさん
2024/12/16(月) 12:39:36.29ID:pEIdxfnL >>104をマルチスレッド対応するなら
まず初心者入門向け版としてはCellをMutexに変更で動く
fn new_id() -> Option<usize> {
static ID: Mutex<usize> = Mutex::new(0);
let mut id = ID.lock().unwrap();
id.checked_add(1).inspect(|&new_id| *id = new_id)
}
まず初心者入門向け版としてはCellをMutexに変更で動く
fn new_id() -> Option<usize> {
static ID: Mutex<usize> = Mutex::new(0);
let mut id = ID.lock().unwrap();
id.checked_add(1).inspect(|&new_id| *id = new_id)
}
111デフォルトの名無しさん
2024/12/16(月) 18:51:07.44ID:gawhGp3+ inspectの間違った使い方
112デフォルトの名無しさん
2024/12/16(月) 19:41:56.01ID:NChejl3+ 正しいようだが何を問題視してる?
ちなみにRustではmatch(またはif let)で書いた時に
次のようなパターンになる場合に
わかりやすく短くメソッドにして繋げることができる
and_then(f)
| Some(x) => f(x),
| None => None,
map(f)
| Some(x) => Some(f(x)),
| None => None,
inspect(f)
| Some(x) => { f(x); Some(x) }
| None => None,
or_else(f)
| Some(x) => Some(x),
| None => f(),
unwrap_or_else(f)
| Some(x) => x,
| None => f(),
ok_or_else(f)
| Some(x) => Ok(x),
| None => Err(f()),
など
ちなみにRustではmatch(またはif let)で書いた時に
次のようなパターンになる場合に
わかりやすく短くメソッドにして繋げることができる
and_then(f)
| Some(x) => f(x),
| None => None,
map(f)
| Some(x) => Some(f(x)),
| None => None,
inspect(f)
| Some(x) => { f(x); Some(x) }
| None => None,
or_else(f)
| Some(x) => Some(x),
| None => f(),
unwrap_or_else(f)
| Some(x) => x,
| None => f(),
ok_or_else(f)
| Some(x) => Ok(x),
| None => Err(f()),
など
113デフォルトの名無しさん
2024/12/17(火) 10:28:51.72ID:hEkGaD6x 全然判り易くないぞ
語彙に直交性が全く無い
語彙に直交性が全く無い
114デフォルトの名無しさん
2024/12/17(火) 12:02:56.17ID:PdC61IaM 語彙の問題もあるのかもしれないけどasyncの問題もあって中の人たち含めみんな昔ほどコンビネータで書かなくなった
115デフォルトの名無しさん
2024/12/17(火) 12:27:03.59ID:QsDK8zUE Optionを自然に真偽値ベースで英語で読むと判り易くなっている
例えばunwrap_or_elseは
真ならunwrapすなわちSome(x)→x
orは前提が偽つまりNoneの場合がfの対象でNone→f()
似ているor_elseは
Some(x)→Some(x)となる部分だけ違うとすぐわかる
その逆は当然and_thenとなり
andは前提が真の場合がfの対象でSome(x)→f(x)となる
通常の動詞1つの時は真つまりSome(x)の時が対象で
mapは値を写像してSome(x)→Some(f(x))
inspectは値を変化させずに実行Some(x)→{ f(&x); Some(x) }
filterも値は変化させずに実行して偽なら捨ててNone
Some(x)→if f(&x) { Some(x) } else { None }
例えばunwrap_or_elseは
真ならunwrapすなわちSome(x)→x
orは前提が偽つまりNoneの場合がfの対象でNone→f()
似ているor_elseは
Some(x)→Some(x)となる部分だけ違うとすぐわかる
その逆は当然and_thenとなり
andは前提が真の場合がfの対象でSome(x)→f(x)となる
通常の動詞1つの時は真つまりSome(x)の時が対象で
mapは値を写像してSome(x)→Some(f(x))
inspectは値を変化させずに実行Some(x)→{ f(&x); Some(x) }
filterも値は変化させずに実行して偽なら捨ててNone
Some(x)→if f(&x) { Some(x) } else { None }
116デフォルトの名無しさん
2024/12/17(火) 13:56:28.23ID:fyM5pHAa 現状追認オジの意見ほど意味のないものはない
117デフォルトの名無しさん
2024/12/17(火) 13:58:12.78ID:8t1OBzHL バカでも読めるコードが正解なんだよ
118デフォルトの名無しさん
2024/12/17(火) 14:25:44.95ID:QOGj4SRI コボラーがそんな事言っていたなw
119デフォルトの名無しさん
2024/12/17(火) 15:37:01.20ID:k3aNgl34 あほくさ。
そこらの医学でも物理でも法律でもいいが適当な論文が単語や言い回しだけ平易にすればバカでも読めるようになるか?
前提知識がないとどうせ意味なんかわからん。
プログラミングも同じ。
理屈が理解できるだけの能がなければ表現ばかり平易にしても無意味。
不必要に難解にする意味はないが、言い回しだけ過度に平易にする意味もない。
そこらの医学でも物理でも法律でもいいが適当な論文が単語や言い回しだけ平易にすればバカでも読めるようになるか?
前提知識がないとどうせ意味なんかわからん。
プログラミングも同じ。
理屈が理解できるだけの能がなければ表現ばかり平易にしても無意味。
不必要に難解にする意味はないが、言い回しだけ過度に平易にする意味もない。
120デフォルトの名無しさん
2024/12/17(火) 15:40:38.28ID:8t1OBzHL 特定のプログラミング言語を使えることを物理医学レベルと思ってるのは思い上がり
121デフォルトの名無しさん
2024/12/17(火) 15:52:02.93ID:k3aNgl34122デフォルトの名無しさん
2024/12/17(火) 15:54:52.82ID:8t1OBzHL123デフォルトの名無しさん
2024/12/17(火) 16:01:39.84ID:k3aNgl34 >>122
それは大変によくわかる。
自分で書いたものすら意味わからんようになるのは普通のことだからな……。
だから意図を表現することが大事で、小さなロジックの断片にでも名前を付ける。
その状況を表すための名前 (専門用語) こそが大事。
訓練されていない人にとって平易であることとは違う。
それは大変によくわかる。
自分で書いたものすら意味わからんようになるのは普通のことだからな……。
だから意図を表現することが大事で、小さなロジックの断片にでも名前を付ける。
その状況を表すための名前 (専門用語) こそが大事。
訓練されていない人にとって平易であることとは違う。
124デフォルトの名無しさん
2024/12/17(火) 16:33:22.09ID:bLYSKCYG >>116
現状追認主義なのに推奨されてる用量・用法は守らず動くだけのコードを披露したがるのは理解できないんだが
現状追認主義なのに推奨されてる用量・用法は守らず動くだけのコードを披露したがるのは理解できないんだが
125デフォルトの名無しさん
2024/12/17(火) 17:43:30.54ID:SHc5Q5Oi ママに褒めてもらいたい幼児の心理だよ
わかりやすいだろ
わかりやすいだろ
126デフォルトの名無しさん
2024/12/17(火) 20:27:48.43ID:QsDK8zUE >>117
「ごっちゃに書いて見通しの悪いコードにはせずに、
高階関数のメソッドチェーンにして、
各々のメソッドで個別に関数またはクロージャで処理を指定する。」
ここまでは共通認識でいいんだよね?
万が一これにも反対の人がいるならばまずは代案を明示的に出してほしい
以上の共通認識の上で
語彙の問題という話が出ているからメソッド名の付け方に問題があるということなのか?
それともメソッドが多すぎる(機能が多すぎる)またはメソッドの分別の仕方に問題があるということなのか?
まさか高階関数がわかりにくいという話ではないと思うが
「ごっちゃに書いて見通しの悪いコードにはせずに、
高階関数のメソッドチェーンにして、
各々のメソッドで個別に関数またはクロージャで処理を指定する。」
ここまでは共通認識でいいんだよね?
万が一これにも反対の人がいるならばまずは代案を明示的に出してほしい
以上の共通認識の上で
語彙の問題という話が出ているからメソッド名の付け方に問題があるということなのか?
それともメソッドが多すぎる(機能が多すぎる)またはメソッドの分別の仕方に問題があるということなのか?
まさか高階関数がわかりにくいという話ではないと思うが
127デフォルトの名無しさん
2024/12/17(火) 21:50:43.67ID:dgkTZZrK128デフォルトの名無しさん
2024/12/17(火) 22:05:47.16ID:ecWnwmom129デフォルトの名無しさん
2024/12/17(火) 22:08:10.40ID:e6YSkvhC >>127
また自分勝手な慣習や思い込みの暗黙の了解かよ
また自分勝手な慣習や思い込みの暗黙の了解かよ
130デフォルトの名無しさん
2024/12/17(火) 22:18:10.64ID:zSkWZLKX vecs.iter().map(|x| x.iter()).flatten().filter(...)
みたいなのは書いてて気持ち良いけど、全員が賛同するわけではないよな
Rustの公式のドキュメントだって関数型スタイルの書き方と手続き型スタイルの書き方の両方を紹介してるわけだし
そういう「高度な書き方」をバッサリ切り捨ててるGO言語が人気というのもそう
みたいなのは書いてて気持ち良いけど、全員が賛同するわけではないよな
Rustの公式のドキュメントだって関数型スタイルの書き方と手続き型スタイルの書き方の両方を紹介してるわけだし
そういう「高度な書き方」をバッサリ切り捨ててるGO言語が人気というのもそう
131デフォルトの名無しさん
2024/12/17(火) 22:20:51.38ID:QsDK8zUE132デフォルトの名無しさん
2024/12/17(火) 22:42:34.79ID:e6YSkvhC133デフォルトの名無しさん
2024/12/17(火) 23:29:57.24ID:zSkWZLKX134デフォルトの名無しさん
2024/12/18(水) 09:42:19.11ID:w442kBzm まあ存在する以上はユースケースがあるってことだからな。
135デフォルトの名無しさん
2024/12/18(水) 12:59:18.01ID:RrhqiCIc コードゴルファーのために存在してるわけじゃないからな
136デフォルトの名無しさん
2024/12/18(水) 13:17:46.53ID:3HdOm/G7 そろそろitertoolsを標準ライブラリ化する話はないのか?
137デフォルトの名無しさん
2024/12/18(水) 18:37:10.88ID:C5X2cUVY 個別に取り入れられてる
まとめて標準化はない
棲み分け
まとめて標準化はない
棲み分け
138デフォルトの名無しさん
2024/12/18(水) 19:09:54.98ID:MW322kuv >>127
そのマルチスレッド対応コードに
指摘の「慣習や暗黙の了解を無視したコード」とやらが見当たらないのだが
そもそも慣習や暗黙の了解とはどういう意味で使ってる?
>> マルチスレッド対応するなら
>> まず初心者入門向け版としてはCellをMutexに変更で動く
>>
>> fn new_id() -> Option<usize> {
>> static ID: Mutex<usize> = Mutex::new(0);
>>
>> let mut id = ID.lock().unwrap();
>> id.checked_add(1).inspect(|&new_id| *id = new_id)
>> }
そのマルチスレッド対応コードに
指摘の「慣習や暗黙の了解を無視したコード」とやらが見当たらないのだが
そもそも慣習や暗黙の了解とはどういう意味で使ってる?
>> マルチスレッド対応するなら
>> まず初心者入門向け版としてはCellをMutexに変更で動く
>>
>> fn new_id() -> Option<usize> {
>> static ID: Mutex<usize> = Mutex::new(0);
>>
>> let mut id = ID.lock().unwrap();
>> id.checked_add(1).inspect(|&new_id| *id = new_id)
>> }
139デフォルトの名無しさん
2024/12/19(木) 11:45:17.60ID:p9TYuGiM140デフォルトの名無しさん
2024/12/19(木) 11:55:22.77ID:953TTIIh 型のキャストは
std::mem::transmute
std::mem::transmute
141デフォルトの名無しさん
2024/12/19(木) 12:16:13.05ID:H/9JfOm9 assert_eq!((3.14_f32).to_bits(), 0b1000000010010001111010111000011_u32);
assert_eq!(f32::from_bits(0b1000000010010001111010111000011_u32), 3.14_f32);
assert_eq!(f32::from_bits(0b1000000010010001111010111000011_u32), 3.14_f32);
142デフォルトの名無しさん
2024/12/20(金) 15:29:01.33ID:raronLtC JAIST、「並行量子通信プロトコル」の完全な自動形式検証を実現
http://news.mynavi.jp/techplus/article/20241220-3090485/
http://news.mynavi.jp/techplus/article/20241220-3090485/
143デフォルトの名無しさん
2024/12/22(日) 22:27:16.01ID:K7zRdssG >>138
中級者向けにはこれでええんかね
fn new_id() -> Option<usize> {
static ID: AtomicUsize = AtomicUsize::new(0);
let mut old_id = ID.load(Relaxed);
while let Some(new_id) = old_id.checked_add(1) {
match ID.compare_exchange_weak(old_id, new_id, Relaxed, Relaxed) {
Ok(_) => return Some(new_id),
Err(updated_old_id) => old_id = updated_old_id,
}
}
None
}
中級者向けにはこれでええんかね
fn new_id() -> Option<usize> {
static ID: AtomicUsize = AtomicUsize::new(0);
let mut old_id = ID.load(Relaxed);
while let Some(new_id) = old_id.checked_add(1) {
match ID.compare_exchange_weak(old_id, new_id, Relaxed, Relaxed) {
Ok(_) => return Some(new_id),
Err(updated_old_id) => old_id = updated_old_id,
}
}
None
}
144デフォルトの名無しさん
2024/12/23(月) 22:20:47.40ID:GhTcJSaR Rustに興味出てきたからとりあえず、とほほさんのサイトに目を通してみたんだけど
…もしかしてあの方、非同期処理と並列処理をごっちゃに理解している?
https://www.tohoho-web.com/ex/rust.html#async-await
…もしかしてあの方、非同期処理と並列処理をごっちゃに理解している?
https://www.tohoho-web.com/ex/rust.html#async-await
145デフォルトの名無しさん
2024/12/23(月) 22:54:25.61ID:OG1FFUyc146デフォルトの名無しさん
2024/12/28(土) 15:51:05.67ID:SGU/9qSb Rustしか勝たん
147デフォルトの名無しさん
2024/12/28(土) 17:09:23.73ID:IXmLUnxX こういうアホが湧いてきたときがピークだな
148デフォルトの名無しさん
2024/12/28(土) 17:20:50.92ID:T6F1mfjg WebAssemblyはRustが主流なイメージだけど実際どんなもんだろ
149デフォルトの名無しさん
2024/12/28(土) 18:28:20.06ID:wm6lCJnC linuxカーネルがシェルスクリプトの付属品にならなかったのはシェルを変更できるから
だがjsは、変更不可能にすればjsが永久に主流だというのを意図的にやっている
だがjsは、変更不可能にすればjsが永久に主流だというのを意図的にやっている
150デフォルトの名無しさん
2025/01/01(水) 12:59:04.47ID:emEmRiID >>149
何いってんだお前?
何いってんだお前?
151デフォルトの名無しさん
2025/01/01(水) 18:48:34.00ID:0dTGHEt/ 触るな触るな
152デフォルトの名無しさん
2025/01/03(金) 23:49:31.66ID:hQWrSYwJ ひといないねこのすれ
153デフォルトの名無しさん
2025/01/04(土) 10:08:52.56ID:9AJmtK0P だからマルチスレッドで発生しうる競合はその2つだけじゃないから
それだけで安全と言い切れるわけないだろ
そもそも安全性ってお前が作るアプリで必要なの?
Linuxカーネルや組み込みだったらわかるけどそんな高度なプログラム作ってんの?
飛行機のシステム作ってて命がかかってるとかならわかるが、その辺のアプリで安全性とかどうでもいいよね
Rust馬鹿信者は開発生産性を軽視しすぎだ、開発生産性を犠牲に安全性に振ってるのがRustだがアプリの特性によって安全性なんぞどうでもいいことが多い
開発生産性が一番重要
それだけで安全と言い切れるわけないだろ
そもそも安全性ってお前が作るアプリで必要なの?
Linuxカーネルや組み込みだったらわかるけどそんな高度なプログラム作ってんの?
飛行機のシステム作ってて命がかかってるとかならわかるが、その辺のアプリで安全性とかどうでもいいよね
Rust馬鹿信者は開発生産性を軽視しすぎだ、開発生産性を犠牲に安全性に振ってるのがRustだがアプリの特性によって安全性なんぞどうでもいいことが多い
開発生産性が一番重要
154デフォルトの名無しさん
2025/01/04(土) 11:56:56.49ID:Z095809L 難しさによる障壁はあるけど、慣れれば生産性自体は高い言語だと思う
ライブラリ多いし、ちょっとしたツールを作る程度ならエラーハンドリングもそんなに頑張らなくて良いし (anyhow を使えば割と雑に書ける)
流石にPythonのような手軽さは無いけど、C++よりは遥かに書きやすいし、個人的にはC#やJavaよりも楽だと思うくらい
これは言語仕様でなくツールの話だけど、プロジェクトを作ったり、ライブラリを追加したりするのが楽
学習コストが高いのはその通りで、誰かが書いたツールを他の人が保守しづらいみたいな問題はどうしようもないけど…
(そういう用途ならGoが良さそう)
ライブラリ多いし、ちょっとしたツールを作る程度ならエラーハンドリングもそんなに頑張らなくて良いし (anyhow を使えば割と雑に書ける)
流石にPythonのような手軽さは無いけど、C++よりは遥かに書きやすいし、個人的にはC#やJavaよりも楽だと思うくらい
これは言語仕様でなくツールの話だけど、プロジェクトを作ったり、ライブラリを追加したりするのが楽
学習コストが高いのはその通りで、誰かが書いたツールを他の人が保守しづらいみたいな問題はどうしようもないけど…
(そういう用途ならGoが良さそう)
155デフォルトの名無しさん
2025/01/04(土) 12:23:29.13ID:5PJMX9Ru156デフォルトの名無しさん
2025/01/04(土) 12:59:21.10ID:OzBQvYrX >>155
「自分がRustに慣れてるなら」それは自分も同意
自分の意見は
・Rustは分かるようになるまでが大変
・理解できれば開発者にとって強力な言語
で、「Goの方が向く」というのはとっつきやすさを含めた話のつもりで書いた
他言語の経験者から見たら、たぶんRustは型やトレイトの意味を理解するのが難しいし、参照などのルールを理解しないとコンパイルすら通らないから、Goの方が触りやすいんじゃないかと思う
Arc, Rc, Cell, Mutex とかの型は分かる人にとってはmeaningfulだけど、初学者がすぐに分かるものではないと思う
「自分がRustに慣れてるなら」それは自分も同意
自分の意見は
・Rustは分かるようになるまでが大変
・理解できれば開発者にとって強力な言語
で、「Goの方が向く」というのはとっつきやすさを含めた話のつもりで書いた
他言語の経験者から見たら、たぶんRustは型やトレイトの意味を理解するのが難しいし、参照などのルールを理解しないとコンパイルすら通らないから、Goの方が触りやすいんじゃないかと思う
Arc, Rc, Cell, Mutex とかの型は分かる人にとってはmeaningfulだけど、初学者がすぐに分かるものではないと思う
157デフォルトの名無しさん
2025/01/04(土) 13:59:36.84ID:5PJMX9Ru >>156
単純にメンテする人員を確保しづらいという意味ならそれはそう
単純にメンテする人員を確保しづらいという意味ならそれはそう
158デフォルトの名無しさん
2025/01/04(土) 22:40:45.82ID:xBPs09Kz rustのいい所はresultやoption.その他色々な型について文脈が大体決まっていること。なので慣れると人が書いたコードでも読みやすい。c#やjavaとの比較であれば開発効率は大体同じか、勝っているぐらい。nullや例外がある言語はプログラムがどうしても汚くなる。
rustはaiにコード生成させた時の品質も割といい。コンパイルエラーでても対応方法が具体的なのでそのままメッセージをaiに渡すだけで直る。
rustはaiにコード生成させた時の品質も割といい。コンパイルエラーでても対応方法が具体的なのでそのままメッセージをaiに渡すだけで直る。
159デフォルトの名無しさん
2025/01/04(土) 22:49:58.13ID:xBPs09Kz AIが当たり前の時代においてはコードの記述量そのものは開発効率に直結するものではなくなる。どの言語でも似たような事は出来る。でも作られたコードが、正しいかどうかは別の問題。
AIはたまに嘘を付くので、それをコンパイラで厳密にチエックする必要がある。そういう意味では関数型言語へのシフトは進むし、rustはいい位置にいると思う。
AIはたまに嘘を付くので、それをコンパイラで厳密にチエックする必要がある。そういう意味では関数型言語へのシフトは進むし、rustはいい位置にいると思う。
160デフォルトの名無しさん
2025/01/04(土) 23:01:31.53ID:tP/ja7AQ 関数型関係ないから
161デフォルトの名無しさん
2025/01/04(土) 23:15:15.09ID:FAAvXSOV >>159
関数型である部分ではなく
Rustが安全性にも役立つ史上最強の型システムを構築したことが決め手かな
特にトレイトそしてトレイト境界
さらに例えばSendやSyncといった概念的なトレイトなど
関数型である部分ではなく
Rustが安全性にも役立つ史上最強の型システムを構築したことが決め手かな
特にトレイトそしてトレイト境界
さらに例えばSendやSyncといった概念的なトレイトなど
162デフォルトの名無しさん
2025/01/05(日) 00:44:18.92ID:TOCT7c8i そうなんだ、Rustってすごいんだね!
163デフォルトの名無しさん
2025/01/05(日) 11:01:38.28ID:8kdOFrcZ 関数型関係ないから
164デフォルトの名無しさん
2025/01/05(日) 13:34:15.55ID:4B4hqpXY お前ら9連休はちゃんと楽しめたか?
165デフォルトの名無しさん
2025/01/05(日) 16:19:33.22ID:mRHgcQU5 九連休に一回もコード書いてない陽キャはこのスレ書き込み禁止な
166デフォルトの名無しさん
2025/01/05(日) 18:30:14.16ID:Rb8d6mKE 体力落ちないように散歩しまくってたら脚の裏に豆出来たよ
167デフォルトの名無しさん
2025/01/05(日) 18:46:31.56ID:7ZREq1Cz 陰キャなのに今年のコード書いてなかった
fn main() {
println!("{}年", (0..10u64).map(|i| i.pow(3)).sum::<u64>());
println!("{}年", (0..10u64).sum::<u64>().pow(2));
}
sum()の型アノテーション外せないの?
fn main() {
println!("{}年", (0..10u64).map(|i| i.pow(3)).sum::<u64>());
println!("{}年", (0..10u64).sum::<u64>().pow(2));
}
sum()の型アノテーション外せないの?
168デフォルトの名無しさん
2025/01/06(月) 00:22:47.46ID:criPfDaa169デフォルトの名無しさん
2025/01/06(月) 00:30:50.77ID:wyPVXQtD その論理は明らかにおかしい
170デフォルトの名無しさん
2025/01/06(月) 03:11:05.95ID:AJFRd04v 0..10がu64なんだからsumの結果も当然u64だろうという気持ちにはなる
171デフォルトの名無しさん
2025/01/06(月) 08:35:26.36ID:wMDzRwfr そこは指定必須
例えばu64の和をu128で求める型を以下のように増やせるから無指定を許すとコードが曖昧になる
struct MySum(u128);
impl std::iter::Sum<u64> for MySum {
fn sum<I: Iterator<Item = u64>>(iter: I) -> Self {
iter.fold(MySum(0), |sum, n| MySum(sum.0 + n as u128))
}
}
fn main() {
// u64の和をu128で計算できる
let x = [u64::MAX, u64::MAX].into_iter().sum::<MySum>().0;
assert_eq!(x, u64::MAX as u128 * 2);
// このコードはデバッグモード時にoverflowして悪手
let x = [u64::MAX, u64::MAX].into_iter().sum::<u64>();
assert_eq!(x, u64::MAX - 1);
// ラップアラウンドさせたいならこうする
use std::num::Wrapping;
let x = [u64::MAX, u64::MAX].into_iter().map(|n| Wrapping(n)).sum::<Wrapping<u64>>().0;
assert_eq!(x, u64::MAX - 1);
}
このように必ず型を指定して使い分けをする
例えばu64の和をu128で求める型を以下のように増やせるから無指定を許すとコードが曖昧になる
struct MySum(u128);
impl std::iter::Sum<u64> for MySum {
fn sum<I: Iterator<Item = u64>>(iter: I) -> Self {
iter.fold(MySum(0), |sum, n| MySum(sum.0 + n as u128))
}
}
fn main() {
// u64の和をu128で計算できる
let x = [u64::MAX, u64::MAX].into_iter().sum::<MySum>().0;
assert_eq!(x, u64::MAX as u128 * 2);
// このコードはデバッグモード時にoverflowして悪手
let x = [u64::MAX, u64::MAX].into_iter().sum::<u64>();
assert_eq!(x, u64::MAX - 1);
// ラップアラウンドさせたいならこうする
use std::num::Wrapping;
let x = [u64::MAX, u64::MAX].into_iter().map(|n| Wrapping(n)).sum::<Wrapping<u64>>().0;
assert_eq!(x, u64::MAX - 1);
}
このように必ず型を指定して使い分けをする
172デフォルトの名無しさん
2025/01/06(月) 16:43:43.88ID:lN8qCLjL Monoidを先に整備すればこんなことにはならずに済んだろうに
173デフォルトの名無しさん
2025/01/06(月) 17:02:00.56ID:jpfBkgv0 >>171
そういうのは本来sumの役割じゃなくないかという気持ち
そういうのは本来sumの役割じゃなくないかという気持ち
174デフォルトの名無しさん
2025/01/06(月) 18:43:17.81ID:tSs1WAlu オーバーフローとかは関係なくて型システムの制約と標準ライブラリの実装方法の問題だよ
175デフォルトの名無しさん
2025/01/06(月) 19:00:20.90ID:9m9l0GJF sum()の戻り値の型をIterator::Itemに固定するとItemが参照型の場合に対応できないな
176デフォルトの名無しさん
2025/01/06(月) 21:13:46.20ID:CO3hUR7m そら固定したらダメだよ
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【中国外務省】日中関係悪化は高市氏に責任と名指しで非難… [BFU★]
- 外務省局長は無言で厳しい表情…日中の高官協議終了か 高市首相“台湾”発言で中国が強硬対応 発言撤回求めたか…★2 [BFU★]
- 政府、株式の配当など金融所得を高齢者の医療保険料や窓口負担に反映する方針を固めた [バイト歴50年★]
- 【維新】吉村知事「中国人観光客だけに頼るビジネスモデル変えていかないといけない」「高市総理の発言は撤回する必要はない」 [Hitzeschleier★]
- 「すごいアイドル出てきた」「かわいすぎる」ラヴィット初登場の美女に視聴者驚き ≠ME櫻井もも [ヴァイヴァー★]
- バービー、 台湾有事の発言の波紋で「たまったもんじゃない」「高市さんに真意は聞きたい」「国民に向けて説明してほしい」 [muffin★]
- 中国高官と話す外務省局長の表情、やばい [175344491]
- 日本政府「高市総理の発言は問題ないと伝え、中国総領事のSNS投稿は問題があると中国に伝えました😊」 [931948549]
- 【高市速報】小野田キミ「中国依存はリスク」断交を示唆か [931948549]
- 【んな専🏡】なんG 姫森ルーナ(・o・🍬)総合スレ🏰【ホロライブ▶】
- 【悲報】高市早苗周辺「支持層が離れるので今更発言を撤回できない」 [935793931]
- 高市早苗、岸田政権(当時)に「台湾有事は日本の有事か」という質問をしていた [175344491]
