公式
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 part24
https://mevius.5ch.net/test/read.cgi/tech/1716759686/
ワッチョイスレ
プログラミング言語 Rust 4【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1514107621/
Rust part25
■ このスレッドは過去ログ倉庫に格納されています
2024/07/31(水) 00:46:26.17ID:DBMWY2QT
2024/08/10(土) 14:13:42.84ID:yKio8xQl
2024/08/10(土) 15:13:38.79ID:qd6SEEuZ
それなのにRustは全然使われない理由って何なのかなあ
97デフォルトの名無しさん
2024/08/10(土) 15:33:50.34ID:NMxi230z クラウドストライクが件のセキュリティソフトを開発し始めた頃はまだRustが安定版になかったし仕方ない
98デフォルトの名無しさん
2024/08/10(土) 15:37:06.14ID:hJCMdysf 言語とビジネスは別の話だからだろ
顧客はソフトウェア製品にお金を出すのであって、「Rustで書かれていること」にお金を払うわけじゃない
既存プロジェクトを置き換えたところで顧客から追加のお金を貰えるわけではないし、置き換えをメインに作業してる間は機能追加などの開発は止まるわけだし
新規開発での採用は進んでると思うぞ
顧客はソフトウェア製品にお金を出すのであって、「Rustで書かれていること」にお金を払うわけじゃない
既存プロジェクトを置き換えたところで顧客から追加のお金を貰えるわけではないし、置き換えをメインに作業してる間は機能追加などの開発は止まるわけだし
新規開発での採用は進んでると思うぞ
2024/08/10(土) 16:01:23.31ID:7leusf5/
以前からのは対策が遅れるの仕方ないよな
ただし新規案件でC++はアウトで言い訳できない
十分に学習とお試しする時間があったのだから
ただし新規案件でC++はアウトで言い訳できない
十分に学習とお試しする時間があったのだから
100デフォルトの名無しさん
2024/08/10(土) 16:03:24.43ID:AQDKnTti もともとC++を使う案件自体が少ないんで
シビアなところは互換性を考慮してC++のまんまだし
シビアなところは互換性を考慮してC++のまんまだし
101デフォルトの名無しさん
2024/08/10(土) 16:16:28.94ID:hldat476 >>99
お前は何様なんだよw
お前は何様なんだよw
103デフォルトの名無しさん
2024/08/10(土) 16:58:24.77ID:dQTVCz1X104デフォルトの名無しさん
2024/08/10(土) 17:14:57.10ID:WA5EFoZj 多分>>76の戻り値をFuga<'a>に直すのが根本的解決だけどうまくいったならもういっか
105デフォルトの名無しさん
2024/08/10(土) 22:48:05.26ID:ogPlSB6Z タウリン好き
WinMacで動くクライアントアプリ書きたかってん
WinMacで動くクライアントアプリ書きたかってん
106デフォルトの名無しさん
2024/08/10(土) 23:49:33.16ID:oQf4NdPP >>104
私の記憶ではそこはやってみたのですが治りませんでしたね
私の記憶ではそこはやってみたのですが治りませんでしたね
107デフォルトの名無しさん
2024/08/11(日) 08:59:52.85ID:aVi0ITMX108デフォルトの名無しさん
2024/08/11(日) 11:53:58.67ID:iWzuk0+l Rustで防げるっていうのは、リストに正常にアクセスできたかチェックを強制されるって意味?
109デフォルトの名無しさん
2024/08/11(日) 12:32:03.37ID:Vk240t5v 標準環境なら範囲外アクセスはpanicして停止する
Cだとそこに有効なデータがあるものと思ってそのまま操作してしまい、その結果何が起きるか分からないということがある (言語でなくOS側のチェックにより防がれることはある)
no-std環境のRustについては自分も詳しくないので誰か書いてくれ
Cだとそこに有効なデータがあるものと思ってそのまま操作してしまい、その結果何が起きるか分からないということがある (言語でなくOS側のチェックにより防がれることはある)
no-std環境のRustについては自分も詳しくないので誰か書いてくれ
110デフォルトの名無しさん
2024/08/11(日) 12:55:28.88ID:GcC/Tgf1 >>108
Rustでは20個の領域を作った時点で
そこをその先頭アドレス=ポインタで指すのではなく
連続体(スライス)を抽象的な参照で指す
もちろんそのスライスへの参照は内部では先頭アドレスと長さになるが抽象的なスライス参照&[T]として扱う
そこからイテレータは20個の個別参照&Tを連続的に返したりインデックス指定によりget(index)でOption<&T>を得たりできる
21個目のアドレスを得たりその中身を見たりすることはsafeの範囲ではできない
Rustでは20個の領域を作った時点で
そこをその先頭アドレス=ポインタで指すのではなく
連続体(スライス)を抽象的な参照で指す
もちろんそのスライスへの参照は内部では先頭アドレスと長さになるが抽象的なスライス参照&[T]として扱う
そこからイテレータは20個の個別参照&Tを連続的に返したりインデックス指定によりget(index)でOption<&T>を得たりできる
21個目のアドレスを得たりその中身を見たりすることはsafeの範囲ではできない
112デフォルトの名無しさん
2024/08/11(日) 14:30:38.38ID:GcC/Tgf1 抽象的なレベルで安全を確保してしまえばその後にそのコードは最適化し放題
生成アセンブルコードはcargo asmでその場で確認できる
生成アセンブルコードはcargo asmでその場で確認できる
113デフォルトの名無しさん
2024/08/11(日) 15:19:18.37ID:1MlIj3rk >>111
範囲内かどうか比較する処理は入る。
ただし、静的に絶対安全と分かる状況なら最適化で消えることもある。
そうでなくても現代的 CPU だと分岐予測によって速度的ペナルティは小さいことが多い。
ゼロコストというわけではないが、 C 風のポインタがあまりにも素朴でミスしやすいことに対する解決法としては十分以上に小さいコストだと考えられている。
今では C++ にもスライス的な、範囲を表すクラスが標準に追加されていて再編成が進んでるのでやっぱりそのほうがよいという時代の潮流があるんだと思う。
範囲内かどうか比較する処理は入る。
ただし、静的に絶対安全と分かる状況なら最適化で消えることもある。
そうでなくても現代的 CPU だと分岐予測によって速度的ペナルティは小さいことが多い。
ゼロコストというわけではないが、 C 風のポインタがあまりにも素朴でミスしやすいことに対する解決法としては十分以上に小さいコストだと考えられている。
今では C++ にもスライス的な、範囲を表すクラスが標準に追加されていて再編成が進んでるのでやっぱりそのほうがよいという時代の潮流があるんだと思う。
114デフォルトの名無しさん
2024/08/11(日) 15:21:08.97ID:aeJBanf7 またいつもの嘘吐きが
115デフォルトの名無しさん
2024/08/11(日) 16:17:49.13ID:x9x8amRR zigはリリースビルドだと範囲チェックをオフにしちゃうらしい
やっぱゼロコストじゃないよね
やっぱゼロコストじゃないよね
116デフォルトの名無しさん
2024/08/11(日) 16:42:50.50ID:cW25bVgR >>111
例えばスライスをforで回してその値を書き込む関数
#[inline(never)]
fn foo(slice: &[i32]) {
for t in slice {
write_volatile!(VOLATILE, *t);
}
}
生成アセンブリコード
::foo:
test rsi, rsi
je .LBB11_3
shl rsi, 2
xor eax, eax
.LBB11_2:
mov ecx, dword ptr [rdi + rax]
mov dword ptr [rip + ::VOLATILE], ecx
add rax, 4
cmp rsi, rax
jne .LBB11_2
.LBB11_3:
ret
範囲内かどうかのチェックはC/C++と同じくループ内で1箇所のみで同じ動作になる
例えばスライスをforで回してその値を書き込む関数
#[inline(never)]
fn foo(slice: &[i32]) {
for t in slice {
write_volatile!(VOLATILE, *t);
}
}
生成アセンブリコード
::foo:
test rsi, rsi
je .LBB11_3
shl rsi, 2
xor eax, eax
.LBB11_2:
mov ecx, dword ptr [rdi + rax]
mov dword ptr [rip + ::VOLATILE], ecx
add rax, 4
cmp rsi, rax
jne .LBB11_2
.LBB11_3:
ret
範囲内かどうかのチェックはC/C++と同じくループ内で1箇所のみで同じ動作になる
117デフォルトの名無しさん
2024/08/11(日) 17:01:54.96ID:Vk240t5v ベアメタル環境でもRustってCより有用なものなの?
安全性は保証しやすくなるとして、書きやすさ (あるいは面倒臭さ) がどれほどのものか
実際経験ある人いる?
安全性は保証しやすくなるとして、書きやすさ (あるいは面倒臭さ) がどれほどのものか
実際経験ある人いる?
118デフォルトの名無しさん
2024/08/11(日) 18:11:06.27ID:1MlIj3rk >>117
内部的には unsafe が必要だけど外に対しては安全性を保障している基礎的な語彙が標準ライブラリにはいっぱいあるじゃん。
ああいう感じの基礎的なものを環境に合わせて作るというのがスタートラインで、それが適切に出来てればベアメタル環境だからといって特別な違いはない。
unsafe を適切に下層レイヤに押し込めれていないと全体に unsafe が頻出して Rust の安全性の恩恵を受けにくいし、
安全性の恩恵を受けられないのに Rust の面倒くさい部分はあるという状況になって嬉しくない。
最初の整備をまじめにやるのがすごく大事。
内部的には unsafe が必要だけど外に対しては安全性を保障している基礎的な語彙が標準ライブラリにはいっぱいあるじゃん。
ああいう感じの基礎的なものを環境に合わせて作るというのがスタートラインで、それが適切に出来てればベアメタル環境だからといって特別な違いはない。
unsafe を適切に下層レイヤに押し込めれていないと全体に unsafe が頻出して Rust の安全性の恩恵を受けにくいし、
安全性の恩恵を受けられないのに Rust の面倒くさい部分はあるという状況になって嬉しくない。
最初の整備をまじめにやるのがすごく大事。
>>116
thx
thx
120デフォルトの名無しさん
2024/08/11(日) 21:00:21.89ID:7p9p1GDG no_stdだとRustの基本的な機能は使えるけど
I/O入出力ライブラリなどが当然ないから
Hello, World!するのにこんな感じなのね
https://zenn.dev/zulinx86/articles/rust-nostd-101#final-code
I/O入出力ライブラリなどが当然ないから
Hello, World!するのにこんな感じなのね
https://zenn.dev/zulinx86/articles/rust-nostd-101#final-code
121デフォルトの名無しさん
2024/08/12(月) 13:11:33.58ID:XQ/hRBSk122デフォルトの名無しさん
2024/08/12(月) 13:21:38.56ID:XQ/hRBSk >>120
ベアメタルって元々そういうもんでそ
ベアメタルって元々そういうもんでそ
123デフォルトの名無しさん
2024/08/12(月) 14:00:36.88ID:zYUAXUFL124デフォルトの名無しさん
2024/08/12(月) 14:04:58.34ID:s7amXorj125デフォルトの名無しさん
2024/08/12(月) 14:12:42.26ID:zYUAXUFL トレイトを使いこなせば便利で快適なのに
難しいと思い込んで使いこなさない人が困るだけ
難しいと思い込んで使いこなさない人が困るだけ
126デフォルトの名無しさん
2024/08/12(月) 14:53:33.48ID:1PYqSgWq 複オジに餌を与えないでください!
みんなが迷惑しています!
みんなが迷惑しています!
127デフォルトの名無しさん
2024/08/12(月) 15:10:33.91ID:CLy07uUA 事前に理想的な設計が出来るなら苦労はないんだが現実はそうではないという話だわな
128デフォルトの名無しさん
2024/08/12(月) 15:15:42.43ID:YiYv/cy+ 新たにtraitを導入する時やリファクタリングで構成を変える時も新たなtrait境界を満たしていけばよくて使い勝手がいいね
129デフォルトの名無しさん
2024/08/12(月) 15:16:59.31ID:KoHKVvuj リファクタリングができない難しいという
人が定期的に出るけど他の言語とも比較して
コード例出してくれ
人が定期的に出るけど他の言語とも比較して
コード例出してくれ
130デフォルトの名無しさん
2024/08/12(月) 15:32:17.85ID:c1LudIob リファクタリングしやすいしにくいの違いの定義がそもそもわからん
そういう意味でも例を頼む
そういう意味でも例を頼む
131デフォルトの名無しさん
2024/08/12(月) 16:20:20.18ID:IbEOTvl2 自分的には「リファクタリングしやすい」=「書き換えミスがコンパイルエラーとして検出されやすい」なので
型強めの静的型(Rust)>型弱めの静的型(C系)>動的型
って感じ
ただ「書き換え時にコンパイルエラーに煩わされない」を重視してて動的型がリファクタリングしやすい派もいるっぽい
(個人的にはエラーにならなくてもいつのまにか動作変わってたら意味なくない?と思うけど…)
型強めの静的型(Rust)>型弱めの静的型(C系)>動的型
って感じ
ただ「書き換え時にコンパイルエラーに煩わされない」を重視してて動的型がリファクタリングしやすい派もいるっぽい
(個人的にはエラーにならなくてもいつのまにか動作変わってたら意味なくない?と思うけど…)
132デフォルトの名無しさん
2024/08/12(月) 17:02:05.11ID:Hka8sI98 ああ,書き換え中にエラーなり警告なりが出るのが煩わしいってことか
大抵の言語でそれはありそうだから,エディタの設定で最後にタイプしてから何秒後にアナライザのチェックを入れるかとかいじればいいのでは
大抵の言語でそれはありそうだから,エディタの設定で最後にタイプしてから何秒後にアナライザのチェックを入れるかとかいじればいいのでは
133デフォルトの名無しさん
2024/08/12(月) 17:13:40.85ID:rd9pnszR JetBrainsがリファクタリング機能の出来具合で比べてみると一目瞭然
静的型付け言語の中では最弱
静的型付け言語の中では最弱
134デフォルトの名無しさん
2024/08/12(月) 17:14:55.12ID:s11pSEyp 前スレでもリファクタリングの話出てたけど
無かったことにしてまた同じ話するの
無かったことにしてまた同じ話するの
135デフォルトの名無しさん
2024/08/12(月) 17:16:15.95ID:CLy07uUA プログラマの中には剛腕タイプというか、脳のメモリが大きくて広い範囲の見通しを付けられる人はいる。
そういう人にとっては抽象レイヤも静的型も邪魔になる。
でもまあそういうのはほんまもんの超人なので普通の人は静的型のほうがいいと思う
そういう人にとっては抽象レイヤも静的型も邪魔になる。
でもまあそういうのはほんまもんの超人なので普通の人は静的型のほうがいいと思う
136デフォルトの名無しさん
2024/08/12(月) 17:23:31.41ID:s11pSEyp 他言語との比較もネタ切れ感無理矢理感が激しくていい加減飽きてきた
137デフォルトの名無しさん
2024/08/12(月) 17:32:40.07ID:hWGH0NP6 昔から静的型付け言語はリファクタリングが不便と主張する人がいるけど
イヤなら動的型付け言語を使っていなさい、で終わる話
イヤなら動的型付け言語を使っていなさい、で終わる話
138デフォルトの名無しさん
2024/08/12(月) 20:58:59.97ID:+jMHtzbv Rustの面倒臭さって静的型付けだけでないと思う
方針が見えてるものを堅く作る分には強いけど、作る→試す→改善するといったサイクルを回すような開発は負荷が大きい
Rustでのゲーム開発を断念したLogLog Gamesが出した文章 (https://loglog.games/blog/leaving-rust-gamedev/) なんかは、全てに同意しないにしても、Rustってそういうデメリットはあるよねって感じるだろうし
方針が見えてるものを堅く作る分には強いけど、作る→試す→改善するといったサイクルを回すような開発は負荷が大きい
Rustでのゲーム開発を断念したLogLog Gamesが出した文章 (https://loglog.games/blog/leaving-rust-gamedev/) なんかは、全てに同意しないにしても、Rustってそういうデメリットはあるよねって感じるだろうし
139デフォルトの名無しさん
2024/08/12(月) 21:02:06.81ID:Bgv7f5Pf matchで全揃い(Some(a), Some(b), Some(c)) =>などができない言語だと確かに面倒かもしれない
484 デフォルトの名無しさん 2024/08/12(月) 17:05:54
Optional型の変数はNoneの場合のハンドリングが必要だから余計に複雑度が増す
だからNoneで明示的に初期化が必要な関数ローカルの状態変数が3つもあるのなら
リファクタリングを検討したほうがいいと思ってる
484 デフォルトの名無しさん 2024/08/12(月) 17:05:54
Optional型の変数はNoneの場合のハンドリングが必要だから余計に複雑度が増す
だからNoneで明示的に初期化が必要な関数ローカルの状態変数が3つもあるのなら
リファクタリングを検討したほうがいいと思ってる
140デフォルトの名無しさん
2024/08/12(月) 21:06:34.61ID:P+uhzEsZ >>138
その人も「Once you get good at Rust all of these problems will go away」と書いているように
Rust流のやり方を身に着ければ消える問題ばかり
その人も「Once you get good at Rust all of these problems will go away」と書いているように
Rust流のやり方を身に着ければ消える問題ばかり
141デフォルトの名無しさん
2024/08/12(月) 21:13:39.00ID:s11pSEyp https://github.com/rust-lang/rust/issues/91639
デフォルトでwarnにもdenyにもなってないけど最重要級のlint見つけたぞい
前スレのライフタイムリファクタの話題が出た時点で教えて欲しかったな……
デフォルトでwarnにもdenyにもなってないけど最重要級のlint見つけたぞい
前スレのライフタイムリファクタの話題が出た時点で教えて欲しかったな……
142デフォルトの名無しさん
2024/08/12(月) 21:19:15.69ID:+jMHtzbv >>140
内容読んでるか?
その反応こそ批判対象の一部だぞ
Rustの根本的な部分で困難が生じていても、Rustコミュニティは「それはあなたがRustのやり方を知らないだけだ」としか言わない、というのを批判してるチャプターだ
内容読んでるか?
その反応こそ批判対象の一部だぞ
Rustの根本的な部分で困難が生じていても、Rustコミュニティは「それはあなたがRustのやり方を知らないだけだ」としか言わない、というのを批判してるチャプターだ
143デフォルトの名無しさん
2024/08/12(月) 21:32:50.85ID:eisITTDv 複オジをRustコミュニティの代表者として扱うなよ
144デフォルトの名無しさん
2024/08/12(月) 21:42:37.55ID:3Ibpt2aV145デフォルトの名無しさん
2024/08/12(月) 22:04:56.11ID:AOmsGFzU146デフォルトの名無しさん
2024/08/12(月) 22:12:53.72ID:s11pSEyp 他言語と比較して優位を示したい向きがメインになってしまうとどうも Rust の問題の存在を否定する方向に向かいがちで良くないな
そう考えるとオナニーコードでレスバやってたほうがいくらかマシだったのかもしれん
そう考えるとオナニーコードでレスバやってたほうがいくらかマシだったのかもしれん
147デフォルトの名無しさん
2024/08/12(月) 23:01:06.12ID:ksJqJtTC リファクタリングの件でも他の件でもいいけど、
他の言語と比較してRustで何が難しくて困っているのかを具体的なコード例で出してくれないと、
話が進まずに個人の感想か空想に終わってしまう。
他の言語と比較してRustで何が難しくて困っているのかを具体的なコード例で出してくれないと、
話が進まずに個人の感想か空想に終わってしまう。
148デフォルトの名無しさん
2024/08/13(火) 12:11:44.59ID:Nsck/Z03 >>131
ミスをコンパイルエラーにしてくれることがプログラム書いて色々試してる時もリファクタリングしてる時も一番重要だもんな
他の言語だと実行時のエラーや実行時のデバッグに依存せざるを得なかったことがRustでは実行前に解決することが多くて開発効率が良くて助かる
ミスをコンパイルエラーにしてくれることがプログラム書いて色々試してる時もリファクタリングしてる時も一番重要だもんな
他の言語だと実行時のエラーや実行時のデバッグに依存せざるを得なかったことがRustでは実行前に解決することが多くて開発効率が良くて助かる
149デフォルトの名無しさん
2024/08/13(火) 12:58:50.63ID:qGcIneKd 設計を変更する際に必要な変更が多いのはありそう
例えば既存のコードをasyncに対応させようとすると、必要なデータを Arc, Mutex で包んだり、参照のせいでSendできないものをOwnedな型に置き換えたり、トレイト境界に Sync + Send を付けてまわったりといった手間が要る
「設計を変更する」と決めたのでなく、「変更するとどうなるか試したい」といった場合でもこういった作業が必要で、その点は面倒かもしれない
必要な変更をコンパイラが教えてくれるのがありがたいというのは自分も同意する
例えば既存のコードをasyncに対応させようとすると、必要なデータを Arc, Mutex で包んだり、参照のせいでSendできないものをOwnedな型に置き換えたり、トレイト境界に Sync + Send を付けてまわったりといった手間が要る
「設計を変更する」と決めたのでなく、「変更するとどうなるか試したい」といった場合でもこういった作業が必要で、その点は面倒かもしれない
必要な変更をコンパイラが教えてくれるのがありがたいというのは自分も同意する
150デフォルトの名無しさん
2024/08/13(火) 13:12:20.55ID:J7fCsAWj >>149
シングルスレッドの言語以外は
メモリを共有するならそれら排他制御が必要となる点で言語に関係なく同じ
メモリを直接共有しない(例えばチャネル使用)ならRustでもそれらは必要ない
つまりRust特有の話ではない
シングルスレッドの言語以外は
メモリを共有するならそれら排他制御が必要となる点で言語に関係なく同じ
メモリを直接共有しない(例えばチャネル使用)ならRustでもそれらは必要ない
つまりRust特有の話ではない
151デフォルトの名無しさん
2024/08/13(火) 13:12:37.07ID:iXbJ0ifY 動的言語に比べて静的言語がリファクタリングしやすいのは当たり前
モダンな言語の中でRustは所有権とライフタイムのせいで他に比べて明らかにリファクタリングが面倒
火を見るより明らかなことなのになぜ必死に否定したがるのか意味がわからない
モダンな言語の中でRustは所有権とライフタイムのせいで他に比べて明らかにリファクタリングが面倒
火を見るより明らかなことなのになぜ必死に否定したがるのか意味がわからない
152デフォルトの名無しさん
2024/08/13(火) 13:14:54.05ID:6c4LDvBa >>149
asyncはリファクタリングとはまた別のRustの弱点
asyncはリファクタリングとはまた別のRustの弱点
153デフォルトの名無しさん
2024/08/13(火) 13:23:07.46ID:MGOQRx4E154デフォルトの名無しさん
2024/08/13(火) 13:28:41.46ID:+eZNFqL6155デフォルトの名無しさん
2024/08/13(火) 13:46:36.22ID:qGcIneKd 非同期による排他は別にしても参照まわりの面倒さはある
&str にするか String にするか、Rc<String> なのか Arc<Mutex<String>> なのかといったものを考える必要があるし、リファクタ/設計変更の際にこれらの置き換え作業が必要になることはある
細かな最適化はできなくても、GC有りの言語がシンプルに1つString型だけ提供しているのは楽といえば楽
なぜエラーになるのかはコンパイラが教えてくれるし、慣れれば分かるものだけど、必要な変更が他の静的言語に比べて多くて面倒というのは否めないでしょ
自分はRustは好きだし良い言語だと思ってるけど、不便が無いとは思わないし、それが分からないのは現実の開発経験が無いんじゃないかとすら思う
&str にするか String にするか、Rc<String> なのか Arc<Mutex<String>> なのかといったものを考える必要があるし、リファクタ/設計変更の際にこれらの置き換え作業が必要になることはある
細かな最適化はできなくても、GC有りの言語がシンプルに1つString型だけ提供しているのは楽といえば楽
なぜエラーになるのかはコンパイラが教えてくれるし、慣れれば分かるものだけど、必要な変更が他の静的言語に比べて多くて面倒というのは否めないでしょ
自分はRustは好きだし良い言語だと思ってるけど、不便が無いとは思わないし、それが分からないのは現実の開発経験が無いんじゃないかとすら思う
156デフォルトの名無しさん
2024/08/13(火) 13:51:51.56ID:FRB3Y3s9 Rustはわかってないとそもそも型チェックに通るコードが書けない
157デフォルトの名無しさん
2024/08/13(火) 14:03:17.07ID:vwwzn05u もっと経験を積むと「なぜエラーになるのかはコンパイラが教えてくれる」どころか「コンパイラはこちらのミスをエラーにしてくれる」すら思い込みだったと気づく時が来る
もう一度貼っておくからよく読むように
特に「5) コンパイルされたならライフタイムの記述は正しい」と「7) コンパイラのエラーメッセージはプログラムの直し方を教えてくれる」
https://github.com/pretzelhammer/rust-blog/blob/master/posts/translations/jp/common-rust-lifetime-misconceptions.md
もう一度貼っておくからよく読むように
特に「5) コンパイルされたならライフタイムの記述は正しい」と「7) コンパイラのエラーメッセージはプログラムの直し方を教えてくれる」
https://github.com/pretzelhammer/rust-blog/blob/master/posts/translations/jp/common-rust-lifetime-misconceptions.md
158デフォルトの名無しさん
2024/08/13(火) 14:04:43.72ID:SFyZa65C Rustの問題じゃないね
チーム適用や実要件に当てはめて見る実務マと趣味マの違い
チーム適用や実要件に当てはめて見る実務マと趣味マの違い
159デフォルトの名無しさん
2024/08/13(火) 16:05:15.51ID:d5oxWZvl >>157
それは詭弁
例えばその「5) コンパイルされたならライフタイムの記述は正しい」
まずこれは参照の安全性を保証するRustとしては常に正しい
もちろん複数の参照が登場する時は色んな組み合わせのライフタイムの付け方がある
それらのうち参照の安全性を保証できる組み合わせのみをコンパイラは通す
コンパイルが通る組み合わせのうちどれが自分の意図なのかは各自の問題となる
もし自分の意図と異なっていた場合はそれが利用されるところで参照が切れてコンパイルエラーとなる
そのため間違っていたことに気づくことができる
そして修正してコンパイルが通れば記述は正しい
その記事の例でもこの流れで正しい記述にたどり着けている
それは詭弁
例えばその「5) コンパイルされたならライフタイムの記述は正しい」
まずこれは参照の安全性を保証するRustとしては常に正しい
もちろん複数の参照が登場する時は色んな組み合わせのライフタイムの付け方がある
それらのうち参照の安全性を保証できる組み合わせのみをコンパイラは通す
コンパイルが通る組み合わせのうちどれが自分の意図なのかは各自の問題となる
もし自分の意図と異なっていた場合はそれが利用されるところで参照が切れてコンパイルエラーとなる
そのため間違っていたことに気づくことができる
そして修正してコンパイルが通れば記述は正しい
その記事の例でもこの流れで正しい記述にたどり着けている
160デフォルトの名無しさん
2024/08/13(火) 17:41:07.28ID:3jlS4CIE 「Rustで作るプログラミング言語」
この本おすすめですか?
この本おすすめですか?
161デフォルトの名無しさん
2024/08/13(火) 17:55:28.98ID:vwwzn05u >>159
利用の仕方が変わると、それに引っ張られて宣言側が正しかったかどうかが変わる、と言いたいの?
利用の仕方が変わると、それに引っ張られて宣言側が正しかったかどうかが変わる、と言いたいの?
162デフォルトの名無しさん
2024/08/13(火) 18:03:57.04ID:d5oxWZvl >>161
一般的にそうなる
例えば二つの参照を引数にとる関数で二つに異なるライフタイムを持たせるかどうかは利用の前提や方針でどちらもありうる
利用する側(やそれを全て想定したtest)でコンパイルが通るならばそのコードは正しい
一般的にそうなる
例えば二つの参照を引数にとる関数で二つに異なるライフタイムを持たせるかどうかは利用の前提や方針でどちらもありうる
利用する側(やそれを全て想定したtest)でコンパイルが通るならばそのコードは正しい
163デフォルトの名無しさん
2024/08/13(火) 18:21:49.94ID:qGcIneKd 「参照を扱う際は適切なライフタイム注釈を書く必要がある」は他の静的言語より面倒という指摘そのものでは?
「適切なライフタイム注釈を書けばコンパイルは通るし、それで安全性が保障される」のは分かってるけど、問題はそこではなくて
「適切なライフタイム注釈を書けばコンパイルは通るし、それで安全性が保障される」のは分かってるけど、問題はそこではなくて
164デフォルトの名無しさん
2024/08/13(火) 18:23:56.90ID:vwwzn05u >>162
なるほどね、「正しいコード」の定義に齟齬があるのね
「5) コンパイルされたならライフタイムの記述は正しい」の「正しい」は「プログラマの意図通りである」の意味だと思って
それを念頭にもう一回読み直してみて
なるほどね、「正しいコード」の定義に齟齬があるのね
「5) コンパイルされたならライフタイムの記述は正しい」の「正しい」は「プログラマの意図通りである」の意味だと思って
それを念頭にもう一回読み直してみて
165デフォルトの名無しさん
2024/08/13(火) 18:27:02.24ID:6FUbHmIE166デフォルトの名無しさん
2024/08/13(火) 18:33:34.80ID:d5oxWZvl167デフォルトの名無しさん
2024/08/13(火) 18:35:53.44ID:G2fhNxh+ 「正しい」という言葉を多用する技術者にまともなやつはいない
168デフォルトの名無しさん
2024/08/13(火) 18:48:09.58ID:qGcIneKd >>165
C/C++に比べても面倒では?
設計で防げる問題/考慮が要らない問題に対して必要以上のガードを書かされる感じ
例えばグローバルな変数 (一度だけ初期化され、以降は不変) に対して Sync が要るのも、初期化が複数スレッドから呼ばれた場合の安全性を保証しないとコンパイルが通らないからだけど、設計上それは要らないって場面はある
シングルスレッドなアプリだったり、マルチスレッドだけどスレッド生成は初期化の後であるいった場合
参照も同じで、設計上無効なデータを指すことがないといえるケースでも、コンパイラを納得させるために手動でライフタイム注釈を書く必要があるといった感じ
C/C++に比べても面倒では?
設計で防げる問題/考慮が要らない問題に対して必要以上のガードを書かされる感じ
例えばグローバルな変数 (一度だけ初期化され、以降は不変) に対して Sync が要るのも、初期化が複数スレッドから呼ばれた場合の安全性を保証しないとコンパイルが通らないからだけど、設計上それは要らないって場面はある
シングルスレッドなアプリだったり、マルチスレッドだけどスレッド生成は初期化の後であるいった場合
参照も同じで、設計上無効なデータを指すことがないといえるケースでも、コンパイラを納得させるために手動でライフタイム注釈を書く必要があるといった感じ
169デフォルトの名無しさん
2024/08/13(火) 18:49:04.65ID:d5oxWZvl170デフォルトの名無しさん
2024/08/13(火) 18:59:01.23ID:6FUbHmIE >>168
スレッド内でしか用いないならばthread_localにより!Syncでも使えるよ
「設計上それは要らない」「設計上無効なデータを指すことがない」という思い込みは絶対にダメ
例えば無効なデータを指さないが&'staticの意味ならばそれを使えばよいのだよ
スレッド内でしか用いないならばthread_localにより!Syncでも使えるよ
「設計上それは要らない」「設計上無効なデータを指すことがない」という思い込みは絶対にダメ
例えば無効なデータを指さないが&'staticの意味ならばそれを使えばよいのだよ
171デフォルトの名無しさん
2024/08/13(火) 19:01:54.22ID:vwwzn05u >>166
想定するケースが最初から全部書けるならそれでいいが、残念ながらそんな現実は無いよ
ソフトウェアテストの7原則のひとつ: 全数テストは不可能
それに、意図はコード化できるものばかりではない、unsafe関数のdoc-commentに書くべきsafety sectionだってそうだろう
コード化できなければ「プログラマの意図」ではないというのならそれも一理あるだろうが、多分誰も同意しないと思うぞ
想定するケースが最初から全部書けるならそれでいいが、残念ながらそんな現実は無いよ
ソフトウェアテストの7原則のひとつ: 全数テストは不可能
それに、意図はコード化できるものばかりではない、unsafe関数のdoc-commentに書くべきsafety sectionだってそうだろう
コード化できなければ「プログラマの意図」ではないというのならそれも一理あるだろうが、多分誰も同意しないと思うぞ
172デフォルトの名無しさん
2024/08/13(火) 19:10:37.01ID:d5oxWZvl >>171
そんな大きな話はなされていない
一般的な話はRustの範囲を超えている
今回はRustのライフタイムの記述が正しいかどうかの話
想定した使い方でコンパイルが通ればそのコードは正しい&安全となる
想定範囲を変えたり広げたりしてコンパイルエラーとなったならばそれに対応すればよい
そんな大きな話はなされていない
一般的な話はRustの範囲を超えている
今回はRustのライフタイムの記述が正しいかどうかの話
想定した使い方でコンパイルが通ればそのコードは正しい&安全となる
想定範囲を変えたり広げたりしてコンパイルエラーとなったならばそれに対応すればよい
173デフォルトの名無しさん
2024/08/13(火) 19:44:50.08ID:qGcIneKd そもそもの話は「他の言語に比べてリファクタや設計変更がしづらい」という話では?
誰も「ライフタイムが提供する安全性が間違ってる」なんてレスはしてないよ
安全性の保証は強力だけど、そのぶん生産性を低下させ得るデメリットもあるよねって話をしてるだけで
誰も「ライフタイムが提供する安全性が間違ってる」なんてレスはしてないよ
安全性の保証は強力だけど、そのぶん生産性を低下させ得るデメリットもあるよねって話をしてるだけで
174デフォルトの名無しさん
2024/08/13(火) 19:53:38.42ID:vwwzn05u >>172
あなたが「コンパイルが通ればそのコードは正しい」というとき、それは利用側と定義側を含むコード全体の正しさのことを言っているんだよね
でも例のブログ記事は、利用側のfn main()の本体に何が書かれていようと、定義側のfn next()はそれ単独で「正しい」か(≒プログラマの意図通りか)を考えられる前提で書かれているんですよ
つまりmain()でnext()を1回呼ぼうが2回呼ぼうが、next()は変えていないんだから想定する意図は変わらない
最初からnext()は間違っていたことが、main()を変えたことで明らかになった、と
そう思ってもう一回読んでみてね?
あなたが「コンパイルが通ればそのコードは正しい」というとき、それは利用側と定義側を含むコード全体の正しさのことを言っているんだよね
でも例のブログ記事は、利用側のfn main()の本体に何が書かれていようと、定義側のfn next()はそれ単独で「正しい」か(≒プログラマの意図通りか)を考えられる前提で書かれているんですよ
つまりmain()でnext()を1回呼ぼうが2回呼ぼうが、next()は変えていないんだから想定する意図は変わらない
最初からnext()は間違っていたことが、main()を変えたことで明らかになった、と
そう思ってもう一回読んでみてね?
175デフォルトの名無しさん
2024/08/13(火) 19:55:05.46ID:qGcIneKd Dioxusのチームもこのような記事を書いている
https://dioxus.notion.site/Dioxus-Labs-High-level-Rust-5fe1f1c9c8334815ad488410d948f05e
GitHub Acceleratorに選ばれるくらい有望なプロジェクトだし、間違いなくレベルの高い開発者が揃ってるチームけど、彼らですらRustの課題を指摘してるわけで
https://dioxus.notion.site/Dioxus-Labs-High-level-Rust-5fe1f1c9c8334815ad488410d948f05e
GitHub Acceleratorに選ばれるくらい有望なプロジェクトだし、間違いなくレベルの高い開発者が揃ってるチームけど、彼らですらRustの課題を指摘してるわけで
176デフォルトの名無しさん
2024/08/13(火) 19:56:59.13ID:6FUbHmIE >>173
ライフタイムをコンパイラがチェックしてくれることで生産性は低下ではなく上昇でしょ
全てのコードを人間がチェックし続けたりチェックし忘れて実行時デバッグとなることが生産性の低下ですね
さらにその参照バグにきづかないままだとセキュリティホールを招いてしまいますよ
ライフタイムをコンパイラがチェックしてくれることで生産性は低下ではなく上昇でしょ
全てのコードを人間がチェックし続けたりチェックし忘れて実行時デバッグとなることが生産性の低下ですね
さらにその参照バグにきづかないままだとセキュリティホールを招いてしまいますよ
177デフォルトの名無しさん
2024/08/13(火) 19:57:14.06ID:w/VnRva3 >>157
めっちゃ判りますωωω
めっちゃ判りますωωω
178デフォルトの名無しさん
2024/08/13(火) 20:05:14.94ID:d5oxWZvl >>174
最初のコードもコンパイラが通ってアサートも通って意図通りに動いている
次のコードはイテレータが返した値を保持したままイテレータを作動させられる仕様への変更 (今回の例は可能だが必ずしも仕様変更できるかどうかは別)
それぞれコンパイルが通れば意図通りに正しく動作している
最初のコードもコンパイラが通ってアサートも通って意図通りに動いている
次のコードはイテレータが返した値を保持したままイテレータを作動させられる仕様への変更 (今回の例は可能だが必ずしも仕様変更できるかどうかは別)
それぞれコンパイルが通れば意図通りに正しく動作している
179デフォルトの名無しさん
2024/08/13(火) 20:07:43.05ID:w/VnRva3 >>174
ほんそれ
ほんそれ
180デフォルトの名無しさん
2024/08/13(火) 21:30:24.68ID:vwwzn05u >>178
アサートも利用側のmain()にあるものなんだから、next()の呼び出し回数の話と同じで
ここからnext()についてのプログラマの想定を読み取ってたら、この記事が理解できないのは当然なんだってば
最初から理解する気が無くてそういう意地悪言ってるんじゃないよね?
修正後のプログラムの後に
> 今こうして前のプログラムを見返してみると、明らかに間違っていましたね。
って書いてあるんだから、これは仕様を変更したじゃなくて、最初から間違っていたのを修正したという体なんですよ
アサートも利用側のmain()にあるものなんだから、next()の呼び出し回数の話と同じで
ここからnext()についてのプログラマの想定を読み取ってたら、この記事が理解できないのは当然なんだってば
最初から理解する気が無くてそういう意地悪言ってるんじゃないよね?
修正後のプログラムの後に
> 今こうして前のプログラムを見返してみると、明らかに間違っていましたね。
って書いてあるんだから、これは仕様を変更したじゃなくて、最初から間違っていたのを修正したという体なんですよ
181デフォルトの名無しさん
2024/08/13(火) 21:51:35.56ID:d5oxWZvl >>180
一番最初に書いたようにその人の詭弁
後者の利用方法に対応する仕様にしたいならば最初からその後者用のアサートを入れたらよい
そうすれば一発でコンパイルエラーになって修正して終わり
ライフタイムに関してはコンパイルが通ればその利用方法については必ず正しい
コンパイルが通ったのに間違っていることはない
一番最初に書いたようにその人の詭弁
後者の利用方法に対応する仕様にしたいならば最初からその後者用のアサートを入れたらよい
そうすれば一発でコンパイルエラーになって修正して終わり
ライフタイムに関してはコンパイルが通ればその利用方法については必ず正しい
コンパイルが通ったのに間違っていることはない
182デフォルトの名無しさん
2024/08/13(火) 22:37:13.69ID:d5oxWZvl もう少しわかりやすい別の例を出すと
struct Foo(&str, &str);
このライフタイム注釈が無いのは当然エラーになるのは置いとくとして
struct Foo<'a>(&'a str, &'a str);
このように宣言しても多くの用途で困ることはなく
むしろこれで都合がよいこともある
つまりこの宣言方法はバグではない
そしてこれでコンパイルが通る範囲の利用方法をしていれば正しく動作する
しかし用途によっては上記では困りエラーとなる利用方法もある
そこで
struct Foo<'a, 'b>(&'a str, &'b str);
このように宣言することで新たな利用方法に対応が可能となる
こちらに変えてもそれでコンパイルが通る範囲の利用方法をしていれば正しく動作する
どちらのケースでもコンパイラが通せば各々の利用範囲でライフタイムの記述は正しい
コンパイラが通したのに間違っているなんてことは起きない
struct Foo(&str, &str);
このライフタイム注釈が無いのは当然エラーになるのは置いとくとして
struct Foo<'a>(&'a str, &'a str);
このように宣言しても多くの用途で困ることはなく
むしろこれで都合がよいこともある
つまりこの宣言方法はバグではない
そしてこれでコンパイルが通る範囲の利用方法をしていれば正しく動作する
しかし用途によっては上記では困りエラーとなる利用方法もある
そこで
struct Foo<'a, 'b>(&'a str, &'b str);
このように宣言することで新たな利用方法に対応が可能となる
こちらに変えてもそれでコンパイルが通る範囲の利用方法をしていれば正しく動作する
どちらのケースでもコンパイラが通せば各々の利用範囲でライフタイムの記述は正しい
コンパイラが通したのに間違っているなんてことは起きない
183デフォルトの名無しさん
2024/08/13(火) 22:44:00.39ID:vwwzn05u >>181
じゃあ別の切り口から
next()を単独で見てみようか
結局、問題の根本は戻り値のbyte(=&self.remainder[0])としてあり得る最大のlifetimeは'remainderなのに、それより小さい'mut_selfを指定してしまっていることだよね
trait実装の場合にはtraitの宣言に合わせるために実際より小さいlifetimeを指定しないといけない場合があるしれないが、この例は単なるミスで'mut_selfでなくてはいけない理由は特に無いということだった
このnext()の定義を単独で見て、おかしなところは本当に何も無いのか?
next()が正しくないということを示すために、main()の内容を考慮する必要が本当にあるのか?
別にコンパイルエラーになることをいちいち確認しなくても、「なんかおかしいなこれ」って早く気付いて修正できるならそのほうがいいでしょ、って個人的には思うけどね
じゃあ別の切り口から
next()を単独で見てみようか
結局、問題の根本は戻り値のbyte(=&self.remainder[0])としてあり得る最大のlifetimeは'remainderなのに、それより小さい'mut_selfを指定してしまっていることだよね
trait実装の場合にはtraitの宣言に合わせるために実際より小さいlifetimeを指定しないといけない場合があるしれないが、この例は単なるミスで'mut_selfでなくてはいけない理由は特に無いということだった
このnext()の定義を単独で見て、おかしなところは本当に何も無いのか?
next()が正しくないということを示すために、main()の内容を考慮する必要が本当にあるのか?
別にコンパイルエラーになることをいちいち確認しなくても、「なんかおかしいなこれ」って早く気付いて修正できるならそのほうがいいでしょ、って個人的には思うけどね
184デフォルトの名無しさん
2024/08/13(火) 22:54:24.44ID:d5oxWZvl185デフォルトの名無しさん
2024/08/13(火) 23:11:58.95ID:vwwzn05u >>184
ここまでのあなたの主張は正確に言えば「*十分に実際のユースケースを反映した利用側コードとともに* コンパイルが通ればライフタイムの記述は正しい」じゃないか
強い前提を置けば正しいと言える確度も高まって当然だろう
勝手に前提を変えて違う結論を導くのは、それこそ詭弁ではないか
ここまでのあなたの主張は正確に言えば「*十分に実際のユースケースを反映した利用側コードとともに* コンパイルが通ればライフタイムの記述は正しい」じゃないか
強い前提を置けば正しいと言える確度も高まって当然だろう
勝手に前提を変えて違う結論を導くのは、それこそ詭弁ではないか
186デフォルトの名無しさん
2024/08/13(火) 23:29:33.49ID:d5oxWZvl 利用方法とその範囲は各実際のケースで各々異なるのだよ
あらゆるケースを想定して対応することは必要ないだけでなく事実上無理なこともあるだろう
必要となるケースのみ対応すればよい
そして必要となるケースはプログラムとして書かれているかテストコードに書く
どのようなケースでもコンパイルが通ればその記述コードは正しい
コンパイルが通ったのに誤動作することは起きない
あらゆるケースを想定して対応することは必要ないだけでなく事実上無理なこともあるだろう
必要となるケースのみ対応すればよい
そして必要となるケースはプログラムとして書かれているかテストコードに書く
どのようなケースでもコンパイルが通ればその記述コードは正しい
コンパイルが通ったのに誤動作することは起きない
187デフォルトの名無しさん
2024/08/13(火) 23:29:58.94ID:vwwzn05u next()で戻り値のlifetimeを不必要に小さくしているのが、単独で見て「普通に考えるとおかしい」と言えるように
>>182の構造体の例も、「普通は」struct Foo<'a, 'b>(&'a str, &'b str);のように分けるべきだろう
例外は実際に.0も.1も同じStringの部分列であることを想定しているような、同じlifetimeを持つ参照から作ることが想定されている場合か、他にもあるかもしれんが
あと例の「Rustのライフタイムについてのよくある誤解」にもある通り、こういう具体的なメンバを想定したlifeitme in pathには'inputとか'bufとか説明的な名前を付けるべきである
そうすれば「あれ、よく考えたらこの.0と.1って同じlifetimeで本当にいいのか」ってことを、利用側でコンパイルエラーになるのを待たず考慮できるとは思わんのかね
'aみたいなテキトウな名前のlifetimeが許されるのは汎用的なコンテナくらいだろう、Iter<'a, T>とかRef<'a, T>とかCow<'a, T>とか
そういう嗅覚というか、経験知みたいな情報は誰も持ち合わせちゃいないのかね
>>182の構造体の例も、「普通は」struct Foo<'a, 'b>(&'a str, &'b str);のように分けるべきだろう
例外は実際に.0も.1も同じStringの部分列であることを想定しているような、同じlifetimeを持つ参照から作ることが想定されている場合か、他にもあるかもしれんが
あと例の「Rustのライフタイムについてのよくある誤解」にもある通り、こういう具体的なメンバを想定したlifeitme in pathには'inputとか'bufとか説明的な名前を付けるべきである
そうすれば「あれ、よく考えたらこの.0と.1って同じlifetimeで本当にいいのか」ってことを、利用側でコンパイルエラーになるのを待たず考慮できるとは思わんのかね
'aみたいなテキトウな名前のlifetimeが許されるのは汎用的なコンテナくらいだろう、Iter<'a, T>とかRef<'a, T>とかCow<'a, T>とか
そういう嗅覚というか、経験知みたいな情報は誰も持ち合わせちゃいないのかね
188デフォルトの名無しさん
2024/08/13(火) 23:36:10.30ID:Hu5uSedp 複オジに何を言ったところで時間の無駄
そろそろ気付いてね
そろそろ気付いてね
189デフォルトの名無しさん
2024/08/13(火) 23:40:06.70ID:d5oxWZvl 同じところで生まれるものしか取り扱わない場合にFoo<'a, 'b, 'c, 'd, 'e>とする必要はない
そこをFoo<'a>でコンパイルが通る使い方をしているならばFoo<'a>で正しい
どちらかが間違っているという変な考えを捨てよう
そこをFoo<'a>でコンパイルが通る使い方をしているならばFoo<'a>で正しい
どちらかが間違っているという変な考えを捨てよう
190デフォルトの名無しさん
2024/08/13(火) 23:46:03.09ID:vwwzn05u191デフォルトの名無しさん
2024/08/13(火) 23:55:49.36ID:LZM61rZJ >>175
読んだ
大雑把な要約
Rustは非常に素晴らしく成功しているがまだ改善できる点がある
一方で既存の言語には問題があり
他の新言語は社会的賛同が低い
そのため唯一の解決方法はRustをさらに改善に導くことである
そこで具体的な改善案を示す
読んだ
大雑把な要約
Rustは非常に素晴らしく成功しているがまだ改善できる点がある
一方で既存の言語には問題があり
他の新言語は社会的賛同が低い
そのため唯一の解決方法はRustをさらに改善に導くことである
そこで具体的な改善案を示す
192デフォルトの名無しさん
2024/08/14(水) 00:30:36.57ID:gAudIBvM >>187
> >>182の構造体の例も、「普通は」struct Foo<'a, 'b>(&'a str, &'b str);のように分けるべきだろう
> 例外は実際に.0も.1も同じStringの部分列であることを想定しているような、同じlifetimeを持つ参照から作ることが想定されている場合か、他にもあるかもしれんが
これについていえば、必要なのは「構造体は自身よりも寿命の短いデータへの参照を持たない」ことなので、基本的には Foo<'a> だけで済むと思う
fn func() {
let a: String = "foo".to_owned();
{
let b: String = "bar".to_owned();
{
let c = Foo{&a, &b};
}
}
}
これはaとbは違う寿命を持つけど、Fooとしては「c が生きているうちに a と b の寿命が尽きない」ことが保証されてれば良いだけなので、aとbの寿命の区別までは必要まではない
だからメンバーは Foo<'a> の寿命である &'a だけで済むという感じ
自分の認識違いだったらすまん
> >>182の構造体の例も、「普通は」struct Foo<'a, 'b>(&'a str, &'b str);のように分けるべきだろう
> 例外は実際に.0も.1も同じStringの部分列であることを想定しているような、同じlifetimeを持つ参照から作ることが想定されている場合か、他にもあるかもしれんが
これについていえば、必要なのは「構造体は自身よりも寿命の短いデータへの参照を持たない」ことなので、基本的には Foo<'a> だけで済むと思う
fn func() {
let a: String = "foo".to_owned();
{
let b: String = "bar".to_owned();
{
let c = Foo{&a, &b};
}
}
}
これはaとbは違う寿命を持つけど、Fooとしては「c が生きているうちに a と b の寿命が尽きない」ことが保証されてれば良いだけなので、aとbの寿命の区別までは必要まではない
だからメンバーは Foo<'a> の寿命である &'a だけで済むという感じ
自分の認識違いだったらすまん
193デフォルトの名無しさん
2024/08/14(水) 00:42:39.43ID:9bQ7P5cg 働け
194デフォルトの名無しさん
2024/08/14(水) 01:41:38.41ID:trbBeScR >>153
ライブラリが乱立してる点
ライブラリが乱立してる点
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 習政権、高市首相への態度硬化 台湾有事発言で連日非難 中国 ★11 [ぐれ★]
- 国内ホテル、既にキャンセルも 訪日客関連業界、事態見守る ★3 [蚤の市★]
- 日本損失1.7兆円に修正 中国渡航自粛の影響試算 [蚤の市★]
- 「どうしようもない」 ため息つくアジアの玄関口 中国の訪日自粛で−福岡市 [蚤の市★]
- 「アベノミクス」で投資対象と化したマンション ローンの低金利続き「年収の12倍」借りる20代出現 [蚤の市★]
- 橋下徹氏 外務省幹部の訪中受け「口だけ番長」へ痛烈指摘 「喧嘩は日本の完敗…なんとかっこ悪い日本か」 [冬月記者★]
- 台湾「高市さんが台湾人の悲願を叶えてくれた!」これじゃ高市さん発言撤回できないぢゃん😰 [523957489]
- 【実況】博衣こよりのえちえち朝こよ🧪
- 高市周辺、さすがに焦り始めるww「小さな火種が火事になりかけている。早く鎮火しなくてはいけない」 [271912485]
- 【高市悲報】神谷「部下が間違えて脱炭素を脱酸素て書いたんですよ😡それ読んだだけなのに挙げ足とるな!小学生か!」 [359965264]
- 【超悲報】中国への武力行使、世論調査で「賛成」「どちらかといえば賛成」48.8% 「反対」「どちらかといえば反対」の44.2%を上回る [314039747]
- 中国「高市が頭を下げて謝罪しない限り、絶対に許さない」 [329329848]
