Rust part25

■ このスレッドは過去ログ倉庫に格納されています
2024/07/31(水) 00:46:26.17ID:DBMWY2QT
公式
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/
2024/08/08(木) 13:55:28.27ID:xUywgMY3
Firefox先生の明日はどっちだ
2024/08/09(金) 06:14:59.59ID:ho+3w6rX
Tauri2.0 Android/iOSでマルチwebviewしたかった
この流れだとVersoになるまで出来なさそう
2024/08/09(金) 10:26:33.54ID:6vJua0o/
タウリン実際どうなん?
実用になる?
2024/08/09(金) 10:41:11.99ID:yHKv01cw
>>73
有用だけど場合による。
75デフォルトの名無しさん
垢版 |
2024/08/09(金) 17:08:58.86ID:k9SqobKt
implementation of `From` is not general enough
= note: `From<&'0 Hoge>` would have to be implemented for the type `Fuga<'_>`,
for any lifetime `'0`...
= note: ...but `From<&'1 Hoge>` is actually implemented for the type `Fuga<'1>`,
for some specific lifetime `'1`


これはどうやって解決するのが普通?
76デフォルトの名無しさん
垢版 |
2024/08/09(金) 17:13:42.47ID:k9SqobKt
こういう実装は書いてあります
impl<'a> From<&'a Hoge> for Fuga<'a> {
fn from(src: &'a Hoge) -> Fuga<'_> {
Fuga::from(なんかの変換(src))
}
}
77デフォルトの名無しさん
垢版 |
2024/08/09(金) 17:18:10.35ID:k9SqobKt
fn moge<T>(a: &str, b: &str) -> i64 where T: for<'a> From<&'a Hoge> {
中身
let m = T::from(hoge);
中身
}

みたいな関数を呼んだ(コンパイル時)ときに >>75 のエラーで止まります
78デフォルトの名無しさん
垢版 |
2024/08/09(金) 17:22:16.81ID:k9SqobKt
呼ぶ方は
let x = moge::<Fuga>(2, 5);
みたいに呼びたいのです
79デフォルトの名無しさん
垢版 |
2024/08/09(金) 17:22:41.31ID:k9SqobKt
fn mame(a: &str, b: &str) -> i64 {
中身
let m = Fuga::from(hoge);
中身
}
としたときは正常にコンパイルも動作もできました
2024/08/09(金) 18:10:20.58ID:KcU/iUYV
>>77
全体が見えないのでなんとも言えないが
>>75のエラーを解決するなら
例えば
fn moge<T>(a: &str, b: &str) -> i64 where T: for<'a> From<&'a Hoge>

fn moge<'a, T: 'a>(a: &str, b: &str) -> i64 where T: From<&'a Hoge>
81デフォルトの名無しさん
垢版 |
2024/08/09(金) 19:57:46.44ID:JtHudt0o
`src` does not live long enough
--- argument requires that `src` is borrowed for `'a`
borrowed value does not live long enough
`src` dropped here while still borrowed
2024/08/09(金) 21:05:31.98ID:tUCUurcu
playgroundに再現する最小限のコードを貼れよ
2024/08/09(金) 21:17:17.11ID:6vJua0o/
タウリンで作られたなんか実用的なアプリある?
2024/08/09(金) 23:57:36.49ID:3boFjk2T
>>83
https://github.com/tauri-apps/awesome-tauri
2024/08/10(土) 00:51:32.88ID:uWTGSvHq
>>84
なんか中国人が多いな
2024/08/10(土) 09:52:32.95ID:3hKdT569
先月の航空業界や病院に政府機関など850万台のWindows端末が影響を受けた世界的な大規模システム障害について、
CrowdStrikeが根本原因分析のレポートを発表しました。

「コンテンツインタープリターは20個の値しか想定していませんでした。
したがって、21番目の値にコンテンツインタープリターがアクセスしようとすると、入力データ配列の末尾を超えて領域外のメモリが読み取られ、
その結果システムがクラッシュしました」と報告しています。

記事
https://gigazine.net/news/20240809-crowdstrike-root-cause-analysis/
2024/08/10(土) 10:02:51.23ID:KZxV9Wds
>>86
Windowsやマイクロソフトは何も悪くなかったのか
2024/08/10(土) 11:11:45.08ID:ymCXtc/f
>>86
Rustを使っていれば防げたな
スライスイテレータが個別のインデックスチェックコスト無しで境界チェックできるから
2024/08/10(土) 12:59:11.84ID:hldat476
Rustを使っていればってのは机上の空論なんだよな
自分でできないことを人に求めるなよと
2024/08/10(土) 13:41:40.63ID:KZxV9Wds
っぱRustだな
91デフォルトの名無しさん
垢版 |
2024/08/10(土) 13:42:02.22ID:hJCMdysf
今までそのプロジェクトに一度も貢献したことの無い人が「Rustで書き直さないの?」ってIssueを立てて即リジェクトされるのを見かける……
なぜかそういう人が好む言語 (彼らが本当にRustを書いているのかは不明)
2024/08/10(土) 13:42:44.88ID:KZxV9Wds
人間がチェックするよりコンパイラに機械的にチェックさせたほうがこういうミスは出ないってことだ
93デフォルトの名無しさん
垢版 |
2024/08/10(土) 13:45:07.25ID:fX5Mv2O+
>>92
今回のクラウドストライクのやらかしは本来はテストコードで見つかるはずの脆弱性なんだけどな
2024/08/10(土) 13:56:12.38ID:WA5EFoZj
Rustで防げる種類バグがあるのは事実でも、Rustに変えるとバグが減ります! と言っちゃうと嘘になる現実があるからみんな苦しんでるんですよ
2024/08/10(土) 14:13:42.84ID:yKio8xQl
>>93
うっかりテストコードが抜けていても
Rustならコンパイラが撥ねてくれるからいいね

>>94
こういう参照バグやメモリ競合バグは確実に減るね
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で書かれていること」にお金を払うわけじゃない
既存プロジェクトを置き換えたところで顧客から追加のお金を貰えるわけではないし、置き換えをメインに作業してる間は機能追加などの開発は止まるわけだし
新規開発での採用は進んでると思うぞ
2024/08/10(土) 16:01:23.31ID:7leusf5/
以前からのは対策が遅れるの仕方ないよな
ただし新規案件でC++はアウトで言い訳できない
十分に学習とお試しする時間があったのだから
2024/08/10(土) 16:03:24.43ID:AQDKnTti
もともとC++を使う案件自体が少ないんで

シビアなところは互換性を考慮してC++のまんまだし
2024/08/10(土) 16:16:28.94ID:hldat476
>>99
お前は何様なんだよw
2024/08/10(土) 16:19:11.72ID:uMi6lmBr
チンパンジーのあいちゃん
103デフォルトの名無しさん
垢版 |
2024/08/10(土) 16:58:24.77ID:dQTVCz1X
>>82
trait 使うのやめて

>>77 の関数を
fn moge<F>(a: &str, b: &str, f: F) -> i64
where F: for<'a> Fn(&'a Hoge) -> Fuga<'_> {
中身
let m = f(hoge);
中身
}
にかえて

>>78 の呼ぶ側を
let x = moge(2, 5, |hoge| Fuga::from(hoge));
にしたらうまくいきました
ほんとうにありがとうございました
2024/08/10(土) 17:14:57.10ID:WA5EFoZj
多分>>76の戻り値をFuga<'a>に直すのが根本的解決だけどうまくいったならもういっか
2024/08/10(土) 22:48:05.26ID:ogPlSB6Z
タウリン好き
WinMacで動くクライアントアプリ書きたかってん
106デフォルトの名無しさん
垢版 |
2024/08/10(土) 23:49:33.16ID:oQf4NdPP
>>104
私の記憶ではそこはやってみたのですが治りませんでしたね
107デフォルトの名無しさん
垢版 |
2024/08/11(日) 08:59:52.85ID:aVi0ITMX
>>86 >>93 ほんそれ
こんなんテストしてれば見つかる話で恥ずかしいレベルの大チョンボ
マイクロソフトはもちろんクラウドストライクを訴えれば良いし
デルタ航空はマイクロソフトとクラウドストライクに5億ドル請求って言ってるけど
マイクロソフトを訴えるのは筋違いなので
デルタ航空以外の被害受けた各社はみんなでクラウドストライクを訴えれば良い
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については自分も詳しくないので誰か書いてくれ
2024/08/11(日) 12:55:28.88ID:GcC/Tgf1
>>108
Rustでは20個の領域を作った時点で
そこをその先頭アドレス=ポインタで指すのではなく
連続体(スライス)を抽象的な参照で指す
もちろんそのスライスへの参照は内部では先頭アドレスと長さになるが抽象的なスライス参照&[T]として扱う
そこからイテレータは20個の個別参照&Tを連続的に返したりインデックス指定によりget(index)でOption<&T>を得たりできる
21個目のアドレスを得たりその中身を見たりすることはsafeの範囲ではできない
2024/08/11(日) 14:07:38.05ID:LL4gnA2q
それはどんなアセンブルコードに落ちているの?
2024/08/11(日) 14:30:38.38ID:GcC/Tgf1
抽象的なレベルで安全を確保してしまえばその後にそのコードは最適化し放題
生成アセンブルコードはcargo asmでその場で確認できる
2024/08/11(日) 15:19:18.37ID:1MlIj3rk
>>111
範囲内かどうか比較する処理は入る。
ただし、静的に絶対安全と分かる状況なら最適化で消えることもある。
そうでなくても現代的 CPU だと分岐予測によって速度的ペナルティは小さいことが多い。
ゼロコストというわけではないが、 C 風のポインタがあまりにも素朴でミスしやすいことに対する解決法としては十分以上に小さいコストだと考えられている。
今では C++ にもスライス的な、範囲を表すクラスが標準に追加されていて再編成が進んでるのでやっぱりそのほうがよいという時代の潮流があるんだと思う。
2024/08/11(日) 15:21:08.97ID:aeJBanf7
またいつもの嘘吐きが
2024/08/11(日) 16:17:49.13ID:x9x8amRR
zigはリリースビルドだと範囲チェックをオフにしちゃうらしい
やっぱゼロコストじゃないよね
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箇所のみで同じ動作になる
117デフォルトの名無しさん
垢版 |
2024/08/11(日) 17:01:54.96ID:Vk240t5v
ベアメタル環境でもRustってCより有用なものなの?
安全性は保証しやすくなるとして、書きやすさ (あるいは面倒臭さ) がどれほどのものか
実際経験ある人いる?
2024/08/11(日) 18:11:06.27ID:1MlIj3rk
>>117
内部的には unsafe が必要だけど外に対しては安全性を保障している基礎的な語彙が標準ライブラリにはいっぱいあるじゃん。
ああいう感じの基礎的なものを環境に合わせて作るというのがスタートラインで、それが適切に出来てればベアメタル環境だからといって特別な違いはない。

unsafe を適切に下層レイヤに押し込めれていないと全体に unsafe が頻出して Rust の安全性の恩恵を受けにくいし、
安全性の恩恵を受けられないのに Rust の面倒くさい部分はあるという状況になって嬉しくない。

最初の整備をまじめにやるのがすごく大事。
2024/08/11(日) 20:48:33.63ID:LL4gnA2q
>>116
thx
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
2024/08/12(月) 13:11:33.58ID:XQ/hRBSk
>>117
保守には良いと思う
リファクタリングには向いていない
2024/08/12(月) 13:21:38.56ID:XQ/hRBSk
>>120
ベアメタルって元々そういうもんでそ
2024/08/12(月) 14:00:36.88ID:zYUAXUFL
>>121
ちゃんとトレイトベースで作っていれば
Rustはリファクタリングもしやすくミスも防げる
2024/08/12(月) 14:04:58.34ID:s7amXorj
>>123
「ちゃんとトレイトベースで作っていれば」
というのが難物という罠。
2024/08/12(月) 14:12:42.26ID:zYUAXUFL
トレイトを使いこなせば便利で快適なのに
難しいと思い込んで使いこなさない人が困るだけ
2024/08/12(月) 14:53:33.48ID:1PYqSgWq
複オジに餌を与えないでください!
みんなが迷惑しています!
2024/08/12(月) 15:10:33.91ID:CLy07uUA
事前に理想的な設計が出来るなら苦労はないんだが現実はそうではないという話だわな
2024/08/12(月) 15:15:42.43ID:YiYv/cy+
新たにtraitを導入する時やリファクタリングで構成を変える時も新たなtrait境界を満たしていけばよくて使い勝手がいいね
2024/08/12(月) 15:16:59.31ID:KoHKVvuj
リファクタリングができない難しいという
人が定期的に出るけど他の言語とも比較して
コード例出してくれ
130デフォルトの名無しさん
垢版 |
2024/08/12(月) 15:32:17.85ID:c1LudIob
リファクタリングしやすいしにくいの違いの定義がそもそもわからん
そういう意味でも例を頼む
2024/08/12(月) 16:20:20.18ID:IbEOTvl2
自分的には「リファクタリングしやすい」=「書き換えミスがコンパイルエラーとして検出されやすい」なので
型強めの静的型(Rust)>型弱めの静的型(C系)>動的型
って感じ
ただ「書き換え時にコンパイルエラーに煩わされない」を重視してて動的型がリファクタリングしやすい派もいるっぽい
(個人的にはエラーにならなくてもいつのまにか動作変わってたら意味なくない?と思うけど…)
2024/08/12(月) 17:02:05.11ID:Hka8sI98
ああ,書き換え中にエラーなり警告なりが出るのが煩わしいってことか
大抵の言語でそれはありそうだから,エディタの設定で最後にタイプしてから何秒後にアナライザのチェックを入れるかとかいじればいいのでは
2024/08/12(月) 17:13:40.85ID:rd9pnszR
JetBrainsがリファクタリング機能の出来具合で比べてみると一目瞭然
静的型付け言語の中では最弱
2024/08/12(月) 17:14:55.12ID:s11pSEyp
前スレでもリファクタリングの話出てたけど
無かったことにしてまた同じ話するの
2024/08/12(月) 17:16:15.95ID:CLy07uUA
プログラマの中には剛腕タイプというか、脳のメモリが大きくて広い範囲の見通しを付けられる人はいる。
そういう人にとっては抽象レイヤも静的型も邪魔になる。

でもまあそういうのはほんまもんの超人なので普通の人は静的型のほうがいいと思う
2024/08/12(月) 17:23:31.41ID:s11pSEyp
他言語との比較もネタ切れ感無理矢理感が激しくていい加減飽きてきた
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ってそういうデメリットはあるよねって感じるだろうし
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つもあるのなら
リファクタリングを検討したほうがいいと思ってる
2024/08/12(月) 21:06:34.61ID:P+uhzEsZ
>>138
その人も「Once you get good at Rust all of these problems will go away」と書いているように
Rust流のやり方を身に着ければ消える問題ばかり
2024/08/12(月) 21:13:39.00ID:s11pSEyp
https://github.com/rust-lang/rust/issues/91639

デフォルトでwarnにもdenyにもなってないけど最重要級のlint見つけたぞい
前スレのライフタイムリファクタの話題が出た時点で教えて欲しかったな……
142デフォルトの名無しさん
垢版 |
2024/08/12(月) 21:19:15.69ID:+jMHtzbv
>>140
内容読んでるか?
その反応こそ批判対象の一部だぞ
Rustの根本的な部分で困難が生じていても、Rustコミュニティは「それはあなたがRustのやり方を知らないだけだ」としか言わない、というのを批判してるチャプターだ
2024/08/12(月) 21:32:50.85ID:eisITTDv
複オジをRustコミュニティの代表者として扱うなよ
2024/08/12(月) 21:42:37.55ID:3Ibpt2aV
>>141
それよりも簡単な解決方法として
ライフタイム'1と'2の相違エラーが出た時点で
その部分の省略ライフタイムを自分で明示的に補ってやればいい
そうすると何が問題だったのかが視覚化される
2024/08/12(月) 22:04:56.11ID:AOmsGFzU
>>139
Pythonでも普通に出来るぞw
論点そこじゃないだろww
2024/08/12(月) 22:12:53.72ID:s11pSEyp
他言語と比較して優位を示したい向きがメインになってしまうとどうも Rust の問題の存在を否定する方向に向かいがちで良くないな
そう考えるとオナニーコードでレスバやってたほうがいくらかマシだったのかもしれん
2024/08/12(月) 23:01:06.12ID:ksJqJtTC
リファクタリングの件でも他の件でもいいけど、
他の言語と比較してRustで何が難しくて困っているのかを具体的なコード例で出してくれないと、
話が進まずに個人の感想か空想に終わってしまう。
2024/08/13(火) 12:11:44.59ID:Nsck/Z03
>>131
ミスをコンパイルエラーにしてくれることがプログラム書いて色々試してる時もリファクタリングしてる時も一番重要だもんな
他の言語だと実行時のエラーや実行時のデバッグに依存せざるを得なかったことがRustでは実行前に解決することが多くて開発効率が良くて助かる
149デフォルトの名無しさん
垢版 |
2024/08/13(火) 12:58:50.63ID:qGcIneKd
設計を変更する際に必要な変更が多いのはありそう
例えば既存のコードをasyncに対応させようとすると、必要なデータを Arc, Mutex で包んだり、参照のせいでSendできないものをOwnedな型に置き換えたり、トレイト境界に Sync + Send を付けてまわったりといった手間が要る
「設計を変更する」と決めたのでなく、「変更するとどうなるか試したい」といった場合でもこういった作業が必要で、その点は面倒かもしれない
必要な変更をコンパイラが教えてくれるのがありがたいというのは自分も同意する
2024/08/13(火) 13:12:20.55ID:J7fCsAWj
>>149
シングルスレッドの言語以外は
メモリを共有するならそれら排他制御が必要となる点で言語に関係なく同じ
メモリを直接共有しない(例えばチャネル使用)ならRustでもそれらは必要ない
つまりRust特有の話ではない
2024/08/13(火) 13:12:37.07ID:iXbJ0ifY
動的言語に比べて静的言語がリファクタリングしやすいのは当たり前
モダンな言語の中でRustは所有権とライフタイムのせいで他に比べて明らかにリファクタリングが面倒

火を見るより明らかなことなのになぜ必死に否定したがるのか意味がわからない
2024/08/13(火) 13:14:54.05ID:6c4LDvBa
>>149
asyncはリファクタリングとはまた別のRustの弱点
2024/08/13(火) 13:23:07.46ID:MGOQRx4E
>>152
Rustのasyncはスタックレスでリソース消費も少なく高速で動作して使い勝手もいいよ
何を根拠に弱点と?
2024/08/13(火) 13:28:41.46ID:+eZNFqL6
>>151
所有権とライフタイムは慣れの問題であり大した問題ではない。
それが出来ない人はGCに依存して遅くメモリ喰いの言語を使っていなさい。
155デフォルトの名無しさん
垢版 |
2024/08/13(火) 13:46:36.22ID:qGcIneKd
非同期による排他は別にしても参照まわりの面倒さはある
&str にするか String にするか、Rc<String> なのか Arc<Mutex<String>> なのかといったものを考える必要があるし、リファクタ/設計変更の際にこれらの置き換え作業が必要になることはある
細かな最適化はできなくても、GC有りの言語がシンプルに1つString型だけ提供しているのは楽といえば楽

なぜエラーになるのかはコンパイラが教えてくれるし、慣れれば分かるものだけど、必要な変更が他の静的言語に比べて多くて面倒というのは否めないでしょ
自分はRustは好きだし良い言語だと思ってるけど、不便が無いとは思わないし、それが分からないのは現実の開発経験が無いんじゃないかとすら思う
2024/08/13(火) 13:51:51.56ID:FRB3Y3s9
Rustはわかってないとそもそも型チェックに通るコードが書けない
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
2024/08/13(火) 14:04:43.72ID:SFyZa65C
Rustの問題じゃないね
チーム適用や実要件に当てはめて見る実務マと趣味マの違い
2024/08/13(火) 16:05:15.51ID:d5oxWZvl
>>157
それは詭弁
例えばその「5) コンパイルされたならライフタイムの記述は正しい」
まずこれは参照の安全性を保証するRustとしては常に正しい

もちろん複数の参照が登場する時は色んな組み合わせのライフタイムの付け方がある
それらのうち参照の安全性を保証できる組み合わせのみをコンパイラは通す
コンパイルが通る組み合わせのうちどれが自分の意図なのかは各自の問題となる

もし自分の意図と異なっていた場合はそれが利用されるところで参照が切れてコンパイルエラーとなる
そのため間違っていたことに気づくことができる
そして修正してコンパイルが通れば記述は正しい
その記事の例でもこの流れで正しい記述にたどり着けている
160デフォルトの名無しさん
垢版 |
2024/08/13(火) 17:41:07.28ID:3jlS4CIE
「Rustで作るプログラミング言語」
この本おすすめですか?
2024/08/13(火) 17:55:28.98ID:vwwzn05u
>>159
利用の仕方が変わると、それに引っ張られて宣言側が正しかったかどうかが変わる、と言いたいの?
2024/08/13(火) 18:03:57.04ID:d5oxWZvl
>>161
一般的にそうなる
例えば二つの参照を引数にとる関数で二つに異なるライフタイムを持たせるかどうかは利用の前提や方針でどちらもありうる
利用する側(やそれを全て想定したtest)でコンパイルが通るならばそのコードは正しい
163デフォルトの名無しさん
垢版 |
2024/08/13(火) 18:21:49.94ID:qGcIneKd
「参照を扱う際は適切なライフタイム注釈を書く必要がある」は他の静的言語より面倒という指摘そのものでは?
「適切なライフタイム注釈を書けばコンパイルは通るし、それで安全性が保障される」のは分かってるけど、問題はそこではなくて
2024/08/13(火) 18:23:56.90ID:vwwzn05u
>>162
なるほどね、「正しいコード」の定義に齟齬があるのね

「5) コンパイルされたならライフタイムの記述は正しい」の「正しい」は「プログラマの意図通りである」の意味だと思って
それを念頭にもう一回読み直してみて
2024/08/13(火) 18:27:02.24ID:6FUbHmIE
>>163
それはRustの問題じゃないよ
GC言語か否かの問題だね
GC言語は参照の有効性を気にしなくてもよい代わりに遅くてメモリを消費するペナルティ
2024/08/13(火) 18:33:34.80ID:d5oxWZvl
>>164
想定する利用ケースでコンパイルが通ればプログラマの意図通りで正しい
>>157の(5)の例もプログラマの意図通りでなかったためコンパイルエラーとなった
そしてコードを修正してコンパイルを通すことで意図通りの正しいコードになった
2024/08/13(火) 18:35:53.44ID:G2fhNxh+
「正しい」という言葉を多用する技術者にまともなやつはいない
168デフォルトの名無しさん
垢版 |
2024/08/13(火) 18:48:09.58ID:qGcIneKd
>>165
C/C++に比べても面倒では?
設計で防げる問題/考慮が要らない問題に対して必要以上のガードを書かされる感じ

例えばグローバルな変数 (一度だけ初期化され、以降は不変) に対して Sync が要るのも、初期化が複数スレッドから呼ばれた場合の安全性を保証しないとコンパイルが通らないからだけど、設計上それは要らないって場面はある
シングルスレッドなアプリだったり、マルチスレッドだけどスレッド生成は初期化の後であるいった場合

参照も同じで、設計上無効なデータを指すことがないといえるケースでも、コンパイラを納得させるために手動でライフタイム注釈を書く必要があるといった感じ
2024/08/13(火) 18:49:04.65ID:d5oxWZvl
>>167
>>157の「5) コンパイルされたならライフタイムの記述は正しい」が合っているかどうかの話が行われている
想定した使い方でコンパイルが通ったならば記述は正しい
何をどう想定するかでコードは変わりうる
2024/08/13(火) 18:59:01.23ID:6FUbHmIE
>>168
スレッド内でしか用いないならばthread_localにより!Syncでも使えるよ
「設計上それは要らない」「設計上無効なデータを指すことがない」という思い込みは絶対にダメ
例えば無効なデータを指さないが&'staticの意味ならばそれを使えばよいのだよ
2024/08/13(火) 19:01:54.22ID:vwwzn05u
>>166
想定するケースが最初から全部書けるならそれでいいが、残念ながらそんな現実は無いよ
ソフトウェアテストの7原則のひとつ: 全数テストは不可能

それに、意図はコード化できるものばかりではない、unsafe関数のdoc-commentに書くべきsafety sectionだってそうだろう
コード化できなければ「プログラマの意図」ではないというのならそれも一理あるだろうが、多分誰も同意しないと思うぞ
■ このスレッドは過去ログ倉庫に格納されています