Rust part26

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2024/09/20(金) 22:18:38.38ID:c48cFuZJ
公式
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 part25
https://mevius.5ch.net/test/read.cgi/tech/1722354386/

ワッチョイスレ
プログラミング言語 Rust 4【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1514107621/
2024/11/09(土) 23:06:21.72ID:6/tB/poi
ロックして解放してロック解除しなければいい
2024/11/09(土) 23:11:14.97ID:Dc7LpAyZ
>>701
基本的な知識を身に着けろよ
正規表現を内部コードにコンパイルして持つ役目がRegex構造体
可変長になるのでVecで持っていて当然ヒープは必須
2024/11/10(日) 00:07:10.13ID:QiolRTDD
>>703
それは現状の内部実装上の都合の話
本質的にヒープが必須という話ではない
文字列リテラルにヒープが必須でないのと同じとでも言えばわかるかな?
2024/11/10(日) 02:33:30.98ID:OGC8ujy2
は~~~~キレそう
2024/11/10(日) 02:34:34.55ID:OGC8ujy2
なんの意味があんねや、このスレ
2024/11/10(日) 02:36:54.54ID:OGC8ujy2
Rustプログラマにとって有益な情報はこれ以上出ないし、まともなRustプログラマは全員逃げたことが確定して久しいので
次スレあたりから「Rust vs 世界中の全言語 Part27」とか「複製おじさんと遊ぼう Part27」とかにしましょっか
他にもスレタイ案募集
2024/11/10(日) 06:48:35.70ID:xIqOi7JH
>>704
おまえバカだろ
正規表現パターンは実行時に確定してコンパイルサイズも実行時に確定し上限サイズはわからない
ヒープは必須だ
709デフォルトの名無しさん
垢版 |
2024/11/10(日) 11:17:24.55ID:dkv1a77w
入力がコンパイル時に確定してるならサイズも確定するでしょ
理屈としては以下のようなものは作れると思う

struct CompTimeRegex<const N: usize> {
 data: [u8; N]
}

// 正規表現オブジェクトをコンパイル時に計算
// サイズは入力に応じて変わる
// 入力はリテラルのみ
let r = make_regex!("+\\d");

面倒だし、それでパフォーマンスが劇的に良くなるわけでも無いだろうから必要性は微妙なところ
詳しくないけど、手続きマクロの中なら計算のためにヒープを使うこともできるよね?
2024/11/10(日) 11:58:38.78ID:WMkhj3nA
BurntSushiのベンチ結果見た?
2024/11/10(日) 12:03:57.56ID:xIqOi7JH
それは入力固定で出力の型も別仕様の別の話だな
regex::Regexは実行時に正規表現が作られてもよく
それをコンパイルするためヒープが
使われている
2024/11/10(日) 12:23:01.33ID:mfp7bShs
正規表現をコンパイルするのと比べてヌル代入を許容するのは極めて容易で
ヌルを代入すればヒープが解放される
2024/11/10(日) 12:27:06.24ID:z1ldQRPb
const文脈って、実際今なんか有効な活用されてるの?
2024/11/10(日) 12:30:28.79ID:z1ldQRPb
ちなみにzigの似た機能は有効活用されまくり
2024/11/10(日) 12:38:27.50ID:OGC8ujy2
ぐちゃぐちゃできるとかできない言ってるが自分で実装する気のある人間は一人もいねえんだろ???
だったら終わりだよ
2024/11/10(日) 13:02:04.64ID:OGC8ujy2
>>711
だから>>709はCompTimeRegexという従来のRegexではない型を作って話を展開してるわけ
ちゃんと読めてる?
2024/11/10(日) 13:06:11.38ID:OGC8ujy2
意図的な誤読、ストローマン論法、誰もがわかりきった説明を脈絡無く貼って議論を拡散させる
マジで不毛
2024/11/10(日) 13:11:04.55ID:OGC8ujy2
結局さ
ヒープは全部開放しなさい派閥は>>661のコードでRegex内部のArcが未解放のままプロセス終了するのは、ええんか??ええんか??どうなんだオラ??って話ってことでええんよな
2024/11/10(日) 13:16:48.60ID:xIqOi7JH
>>716
全く別の話であり、これまでのregex::Regexについての話への言及・反論にはなっていないことを自覚できているならそれでよろしい
2024/11/10(日) 13:18:41.74ID:nOHdM7oG
>>718
Rustの標準ライブラリstdは
プログラム終了時に自動的にメモリが解放されるようなまともなOS環境を対象にしていて区別しているので大丈夫
OS無しの組み込み環境では#![no_std]を宣言してcoreライブラリのみサポートされる中でのプログラミングを行なう
2024/11/10(日) 14:48:06.15ID:AfmJKCJ3
>>707
みんな何処に逃げた?
2024/11/10(日) 15:04:06.89ID:qC3Ky4ZL
>>661
スコープを外れた場合と同じようにモジュールがアンロードされる際にデストラクトされる
2024/11/10(日) 16:19:33.44ID:OGC8ujy2
>>720
OS側でプロセスを終了させる際にメモリマップを捨てる処理のことを「解放」って呼んでるから君と君以外で話がすれ違うんだと思うよ
2024/11/10(日) 16:24:01.76ID:OGC8ujy2
あと、ええんかオラ?ってのは俺の直接の質問ではない、それに答えられてもへえそうですか
元の議題は>>661、さらに遡れば>>593であって、議題内容はそれでよいか?という確認をしているだけだ
2024/11/10(日) 16:26:17.63ID:OGC8ujy2
>>721
非匿名でまともな交流ができるコミュニティかもね
rust-jpのzulipとか、あるいは英語を頑張って公式コミュニティとかに行ったか、発言しなくてもROM専してるかも
726デフォルトの名無しさん
垢版 |
2024/11/10(日) 16:30:14.58ID:dkv1a77w
5chで聞くよりもChatGPTの方が適切な回答をくれると思う
Rustに限らず他の言語でも
2024/11/10(日) 16:34:57.50ID:OGC8ujy2
ChatGPTもついでにCopilot Chatもゴミだよ
省略されたライフタイムの展開が自分でやったのが合ってるか自信がなくて、試しにやらせてみたらメチャクチャなことばっか言いやがった挙げ句、キレてthe Refrenceのelision rulesのところをペタペタ3回くらいコピペしたらすみません間違っていました、何度も申し訳ございません言いながらやっと正解を返してくれた
決定論的な問題を解かせるのにはまったく向いてない
2024/11/10(日) 16:36:43.08ID:z1ldQRPb
>>727
最初からキレて始めればいいのでは?
2024/11/10(日) 16:39:08.93ID:OGC8ujy2
英語が話せる人はこっちに移住しよう!!! できない人もDeepL片手にカモン!!!
https://www.rust-lang.org/community

日本語コミュはこちら!!!ってかいい加減放置されきった翻訳版の責任者のケツ叩きに行こうぜ!!!
https://rust-lang-jp.zulipchat.com/
2024/11/10(日) 16:41:30.83ID:tFJCBt9m
>>728
キレるはともかく最初からelision rules貼ればよかった説は確かにそう、残念ながら二回目の機会がないが次はそうしてみるぜ
でもよお……こんなのrust-analyzerが完璧なinlay hint実装してくれりゃやらなくて済む話でもあるんだぜ
2024/11/10(日) 16:42:25.60ID:OGC8ujy2
およ? ID変わった
ID:OGC8ujy2=ID:tFJCBt9mです
2024/11/10(日) 16:53:56.32ID:ES+o9VJl
>>722
staticはdrop呼ばれない
2024/11/10(日) 17:11:30.76ID:a6nPaG4v
C++ で static オブジェクトの初期化順 (解体順) は問題を起こしがちだし、いっそそのへんは取り扱わないというのも妥当な判断のひとつではあるわな。
2024/11/10(日) 17:43:15.44ID:mfp7bShs
自動化をあきらめることは賛成
だが手動で解放する技術を不要な技術と見なすことには反対する
735デフォルトの名無しさん
垢版 |
2024/11/10(日) 18:43:44.99ID:dkv1a77w
StringやVecみたいなヒープを使う型をstaticで管理させた場合って、valgrindみたいなメモリリーク検出ツールに引っかかったりする?
dropが呼ばれなくても終了時に一応はメモリ解放してるのか、それとも本当に何もしていないのか
2024/11/10(日) 19:15:15.74ID:xIqOi7JH
>>733
Rustならstatic変数初期化はOnceLockやLazyLockでマルチスレッド競合を含めて安全に初期化できる
static変数でdropはプログラムの終了時も起きないがメモリ解放問題は普通のOS環境では関係ないため問題ない
どうしてもdropしたいなら例えばOptionで包んでtake()で取り出すなどで手動drop()が可能

>>735
手動dropしないならばヒープ領域を持っていても解放されない
これはBox::leak()などで意図的にメモリを解放しないようにした場合でも同様
普通のOS環境ならこれでも問題は全く起きないが
組み込み環境などで確実にメモリ解放したいならば用意するメモリアロケータで対応する
つまりプログラム終了時にメモリアロケータを呼び出して管理している全メモリを解放させればよい
2024/11/10(日) 19:59:43.87ID:tFJCBt9m
質問の答えになってないし、組み込み環境で「プログラムが終了」したり、「管理している全メモリを解放」できるアロケータが必要などとまで言い出した

いやはや
2024/11/10(日) 20:16:38.46ID:tFJCBt9m
>>735
>>661に適当にこれだけのmain足してvalgrindかけてみた

fn main() {
let s = "2021/07/04";
let (year, month, day) = yyyymmdd(s).unwrap();
println!("{}-{}-{}", year, month, day);
}

https://pastebin.com/UN84vEFb

まあ、リーク扱いで出るよね
こういうのがあんまり多いとマジのリークと区別付きづらくて大変そうだけど、なんかアノテーションみたいなので対策できたりするのかな?
739デフォルトの名無しさん
垢版 |
2024/11/10(日) 20:28:05.31ID:dkv1a77w
>>738
サンクス
過去にC++で似たようなケースで顧客から「あなたの所のライブラリを使うとメモリリークが検出されるんだけど?」って指摘されたことがあって気になった
説明して伝わる相手なら良いけど、そういう面倒な人からのクレームを避けたい場合はstaticは避けたほうが良さそうだな
本質的には重要な問題でないと思うけども
2024/11/10(日) 20:28:35.21ID:xIqOi7JH
>>737
組み込み環境であろうとなかろうと各プログラムは終了する
さらにOS環境でOS内であっても各カーネルモジュールのプログラムはアンロードで終了する
一方でもし完全にモノリシックな一つのシステムなら終了後をそもそも考える必要がない

メモリアロケータについては自作したことあるなら管理してるメモリの全解放なんて楽勝だと理解できるだろ
割り当て用に確保しているバッファを返却するだけだ
2024/11/10(日) 20:52:25.18ID:Qvjt9L31
お前ら、Rustでプログラム書いた後にvalgrind ってるの?
もうそういうの終わりにしたいからRust使ってるんじゃないの?
2024/11/10(日) 20:53:16.70ID:tFJCBt9m
相変らず単語ひとつひとつが独自用法すぎて解読が困難だね

mallocみたいなグローバルアロケータを自分で実装しようという話をしているのか?
それとも(allocator_apiがいまだにunstableなせいでボイラープレートモリモリ書かされる)typed_arenaやbumpaloのようなカスタムアロケータの話をしているのか?

前者だとしたらバッファという言葉が出てくるのがまず分からない、もしかしてヒープ領域全体のことをバッファと呼んでいて、確保/解放はsbrkのことを言っているのか?
後者だと「管理してるメモリの全解放」ですべての内容のDropしないといけなくて……って考えるとどう考えてもゲロクソむずいけど、全オブジェクトをManuallyDropに包んで返して責任放棄するのかな……
2024/11/10(日) 20:56:00.86ID:tFJCBt9m
>>741
できねーもんはできねーんだから適切な道具を使うんだよ、笑うならそこの嘘吐き宣教師を笑うんだな
2024/11/10(日) 21:08:26.24ID:xIqOi7JH
>>742
プログラム本体終了後のメモリ解放のためにdropは必要ない
プログラム全体終了後のメモリリークが組み込みなどで困るケースが対象なのだからそれらメモリを返却するだけでよい

sbrkのあるOS環境ならsbrkでOSへ全メモリを返還できるのはその通りだが
それをしなくてもプログラム終了後にメモリリークは起きないので普通のアロケータでは行われていない
メモリリークが起きうる特殊なOSや組み込みならアロケータが借りてるメモリを全返却すればよい
2024/11/10(日) 21:16:26.31ID:tFJCBt9m
>>744
んでどっちのアロケータの話をしてるの?って
2024/11/10(日) 21:22:25.58ID:xIqOi7JH
>>745
普通の仮想メモリOS環境ならstaticでもBox::leakでもプログラム終了後にメモリリークは起きないから対策の必要がない
そうでない特殊なOSや組み込み環境ならばそれ用に用意するメモリアロケータをプログラム終了直前に呼び出して全メモリ返却させればメモリリークは起きない
2024/11/10(日) 21:35:16.61ID:tFJCBt9m
>>746
グローバルアロケータの話をしてんのか、カスタムアロケータの話をしてんのか、って聞いてんだよ

自分の頭の中の理屈をダンプするんじゃなく、言葉の定義をすり合わせる努力をしろ
2024/11/10(日) 21:41:49.64ID:tFJCBt9m
少なくともvalgrindとかperfmonみたいなやつは、プログラム終了時にヒープを辿って解放済みマークの無い場所を見つけたらリークって報告するんだし、一般的にはそれがリークだよ
プロセス終了時にメモリマップの割り当てが解除されるとか、どうでもええわ
2024/11/10(日) 21:48:10.22ID:xIqOi7JH
>>747
Rustでは#[global_allocator]指定でカスタムなグローバルアロケータを使える
プログラム終了後にメモリリークが起きうる組み込み環境なら対応した自作のアロケータを実装してそのように指定して用いる
750デフォルトの名無しさん
垢版 |
2024/11/10(日) 22:10:00.14ID:E3OFY7Tp
>>729
May I talk about the ownership reproduction in the formal community web page?
2024/11/10(日) 22:15:02.72ID:tFJCBt9m
> プログラム終了後にメモリリークが起きうる組み込み環境
組み込みやったことないから知らんけど、そんな環境があんの?
2024/11/10(日) 22:27:44.25ID:tFJCBt9m
https://github.com/rust-embedded/embedded-alloc

組み込みの典型的なコードってこのREADMEのサンプルコードみたいなんでいいのかね
プログラム(main)は終了しない
ヒープの「解放」処理も無い
合ってるよな?

自由に使える物理アドレス空間の一部を実行時アロケーションのために使用するってだけなら、使い終わりにやる「解放」の処理というのは何の話を言ってるんだ? って思ってたけど
そんなものはない、で合ってるのよな?
2024/11/10(日) 22:31:44.37ID:tFJCBt9m
>>750
search first
2024/11/10(日) 22:33:46.00ID:xIqOi7JH
>>751
そういう特殊な環境を出してるのは俺ではないからね
すべてを明示的に解放しなくても我々が普通に使っている仮想メモリ利用では問題ないよという話と
組み込みだとそんな仮定はできなくてメモリリークしていく可能性があるよという話の両方が出ているから
後者でも対応したメモリアロケータを用意すれば対応できるよと解決策を示した
755デフォルトの名無しさん
垢版 |
2024/11/10(日) 22:41:08.35ID:E3OFY7Tp
>>753
What do you mean? What I want to do is talking and having a discussion, not searching.
2024/11/10(日) 22:48:01.15ID:tFJCBt9m
>>754
> そういう特殊な環境を出してるのは俺ではないからね
あれ、そうだっけって思って辿ってみたら言い出してたの>>604だったわ
やっぱお前じゃねーか複おじ

プロセスにしろ組み込みのプログラムにしろ、OSだかシステムファームウェアだかの外部の管理者的存在が行儀の悪いやつのケツを拭いてくれてるだけのことを、
常識的のあるプログラマは「リークしていない」とは言わないんだよ
2024/11/10(日) 23:04:28.91ID:nOHdM7oG
プログラムの最後に行儀よくbrkやsbrkでOSへメモリを解放しているアロケーターを見たことないな
OSにとってはどうでもいいことだからそんな行儀よさは不要なのだろう
ましてやアロケーターの内部でフラグなどをオフにするだけのfree()はプログラムの最後にいらない
実行中に再利用できるようにするかどうかが本質だろうね
2024/11/10(日) 23:16:52.46ID:tFJCBt9m
えーではリークの定義に関して直接的反論はなしということで
以下はすべて誤りであったということでよろしいですね
対戦ありがとうございました

>>593「freeせずにプログラムが終了したり落ちたりしてもメモリリークは起きない」
>>604「freeを忘れてもあるいはfreeせぬまま異常終了となってもその仕組みによりメモリリークは起きない」
>>631「そしてfree()せずにプログラムが終了してもメモリリークは起きない」
>>744「sbrkのあるOS環境ならsbrkでOSへ全メモリを返還できるのはその通りだがそれをしなくてもプログラム終了後にメモリリークは起きない」
>>746「普通の仮想メモリOS環境ならstaticでもBox::leakでもプログラム終了後にメモリリークは起きない」
「そうでない特殊なOSや組み込み環境ならばそれ用に用意するメモリアロケータをプログラム終了直前に呼び出して全メモリ返却させればメモリリークは起きない」
2024/11/10(日) 23:26:36.38ID:mfp7bShs
static mutは明らかにunsafeなわけだが
紙一重でunsafeとは言えないstatic変数のことを
警戒するかそれとも無駄な警備を極限まで捨てた合理主義の皇帝みたいに思うか
そういう対立はよくある
2024/11/10(日) 23:33:02.28ID:xIqOi7JH
プログラム終了後にメモリリークが起きるとすればOSが面倒をみてくれない環境だけだから
そういう環境では特殊な専用のメモリアロケータを用意するしかないだろうね
それならその自作のメモリアロケータをプログラム終了時に呼んで後始末させればメモリリークは防げる
Rustのstaticでヒープを持つ型を使っても最後まで使うメモリをBox::leak()で確保してもメモリリークは起こらないので安心していい
2024/11/11(月) 00:17:42.59ID:4hLj+VPf
Windows/Linux/macOSあたりなら
ファイルハンドルを閉じずにプログラム終了しても
OSが閉じてくれるから何の問題もない
的な主張?
2024/11/11(月) 00:20:13.67ID:VUm74iyn
> プログラム終了後にメモリリークが起きるとすればOSが面倒をみてくれない環境
また実在しない環境の話し始めた
2024/11/11(月) 00:28:54.94ID:VUm74iyn
間違いを認めなくても勝手にすりゃいいけど、そんなんじゃ誰とも意思疎通できないままだぞ
いくら長文を書き連ねても一緒
2024/11/11(月) 00:56:28.26ID:If7GINDb
2種類ある

OSレベルのclose (例えばC言語でのシステムコールを呼ぶclose()) ならばOSが処理してくれるので異常終了含めてプログラム終了時にcloseしていなくても構わない
ただし各言語ライブラリのバッファリングなど他の機能を持つcloseはプログラム終了までに自分でcloseしないとその機能が完遂しない

一方でメモリ解放の場合
OSレベルのメモリ解放 (例えばbrk/sbrk) ならばOSがそのプログラムの仮想メモリ全体を無効にするのでプログラム終了時に解放していなくても構わない
メモリアロケーターライブラリのレベルのメモリ解放 (例えばfree()) もOSにとっては全く無関係な話なのでプログラム終了時に解放していなくても構わない
2024/11/11(月) 01:04:17.69ID:S8QwpOFj
組み込みは詳しくないんだが今ってOSを使わない
組み込みでRustとか使うの?
Rustのターゲットって多分何らかのOSありきだよね
2024/11/11(月) 01:08:33.73ID:BN15+aOP
>>765
語尾にオジを付けな
2024/11/11(月) 01:10:52.04ID:S8QwpOFj
マ板久々なので意味がわからないww
2024/11/11(月) 01:11:20.28ID:S8QwpOFj
webassemblyもなんか微妙な感じだしもったいない
2024/11/11(月) 01:13:05.34ID:BN15+aOP
>>767
そっか、じゃあ過去のRust本スレを4年分復習してきな
あとここはム板だボケジジイ
2024/11/11(月) 01:16:21.72ID:S8QwpOFj
すまんのうww
2024/11/11(月) 01:27:50.38ID:If7GINDb
>>765
OS無しにも対応している
Rustの標準ライブラリstd::はOS前提の機能も入っていてOS無しだと機能しないものもある
Rustの必須な言語機能はcore::ライブラリに部分に分離してまとめてあるので
ベアメタルな組み込みなどではstd::を使わない#![no-std]を指定してcore::を使う
core::では数値型や配列やスライスに文字列(str)およびその複合型が使えるがヒープは対象外なのでVecやStringは標準機能としては使えないといった違いがある
2024/11/11(月) 01:31:24.31ID:If7GINDb
>>768
Wasm自体ブラウザ内も外もどんどん利用が増えてる
もちろんRustで記述が定番化してる
2024/11/11(月) 01:32:59.90ID:BN15+aOP
>>771
とこういった感じの書き込みをするRust信者が複おじ
このスレを読む上での必須知識だから覚えておくように
2024/11/11(月) 07:39:38.28ID:P9CdfRTw
>>732
これ本当?
そうだとするとstatic使った動的ライブラリをアンロードしたら本物のリークが起きる可能性があるが。
2024/11/11(月) 09:19:55.92ID:S9DN3uey
>727
rustの質問するならclaude ai 3.5 sonetが圧倒的に優秀よ。
776デフォルトの名無しさん
垢版 |
2024/11/11(月) 12:55:36.23ID:Bg57iHzA
In the rust forum, we have to use English. How can I say “複おじ”? “Reproduction codger”?
777デフォルトの名無しさん
垢版 |
2024/11/11(月) 13:34:10.78ID:RXw/cl7Z
>>727
ほんまにごみ
数学的な(結論出てる)質問しても平気で間違う
2024/11/11(月) 13:55:19.20ID:kpiTidm5
RustというかCargoの質問なんだけど
crates.ioにリリースしてるもので
一つのcrateでバージョンがいくつかあって
最新のバージョンだけ残して他全部yankedにしてるのに
閲覧回数レポート(crateトップページの下の方の折れ線グラフ)で
yankedされてるバージョンがいつまでもアクセスがあって増え続けて
最新の方がそっちの勢いほどには増えてない
どういう原因が考えられる?
2024/11/11(月) 14:34:31.51ID:xigD4A3Y
>>778
単純にyankされたバージョン使ってる(つまりCargo.lockにそのバージョンが載ってる)ユーザが多いってだけでは?
yankしたからといって既存のユーザが使用禁止になるわけではないので
780デフォルトの名無しさん
垢版 |
2024/11/11(月) 22:49:05.67ID:MbvyOF01
>>551
Rustはリファクタリングや機能拡張保守などに適した言語と言われている
強力な静的型付け、借用チェック、参照競合チェック、メモリ競合チェックなどによりコードが思わず壊れることを防ぐとともに
問題点を実行時エラーや実行時デバッグへと遅らせてしまうことを最も少なくしてくれる言語である
そのため全体の開発変更時間が他の言語より短く済んでいる

また、トレイトとトレイト境界による自然なジェネリック化がレイヤー分離独立と最小限の変更での機能追加を容易にしている
どうしてもトレイト設計をし直さなければならない大規模改修の場合でも、上述のように盤石に機能するコードとするまでが早い
781デフォルトの名無しさん
垢版 |
2024/11/11(月) 22:59:26.02ID:8PeapwRR
借用まわりで質問させてくれ

struct Foo {
 data: Option<Vec<u8>>
}

impl Foo {
 fn do_something(&mut self) -> &mut [u8] {
  if let Some(x) = &mut self.data {
   return x;
  }

  // `self.data` is assigned to here but it was already borrowed
  self.data = Some(vec![0u8; 10]);
  self.data.as_mut().unwrap()
 }
}

これで self.data への代入の際に「既に借用されている」というエラーが出るんだけど、これって回避できない?
最初の借用が if let Some(x) = ... の箇所で行われていることは理解できるんだけど、
if let のスコープを抜けても借用された状態が続く (以降のコードでの借用ができない) のが腑に落ちない
782デフォルトの名無しさん
垢版 |
2024/11/11(月) 23:19:09.36ID:PqwBaVS/
>>781
fn do_something(&mut self) -> &mut [u8] {
if self.data.is_none() {
self.data = Some(vec![0u8; 10]);
}
self.data.as_mut().unwrap()
}
2024/11/11(月) 23:31:21.84ID:VT05MWRT
>>774
Static items do not call drop at the end of the program.
https://doc.rust-lang.org/reference/items/static-items.html

Drop types placed in statics WILL leak.
https://github.com/rust-lang/rfcs/pull/1440
784デフォルトの名無しさん
垢版 |
2024/11/11(月) 23:46:08.88ID:8PeapwRR
>>782
ありがと、これで回避できた
けど借用のルールはまだいまいち分かってない…
785デフォルトの名無しさん
垢版 |
2024/11/11(月) 23:52:53.38ID:PqwBaVS/
staticはモジュールアンロードする可能性があるなら始末する時に手動dropできるように対処するしかないな
アンロードしないなら問題なし
2024/11/12(火) 00:02:28.18ID:h5v4AbHm
>>782
えーとOptionがnoneのとき値を入れたいという場合はもっと簡単に書けて

fn do_something()->&mut [u8] {
self.get_or_insert(vec![1,2,3])
}

という感じ。
2024/11/12(火) 00:12:38.06ID:syNPHnUf
>>781
&mut self.dataにも所有者がある
この匿名の所有者の寿命を'a
型を&'b mut T
とする
'bは'aより長いから'aがいくら短くても、借用された状態が続く

匿名をやめて名前をつければその名前でアクセスできる
2024/11/12(火) 00:13:32.91ID:crz7XiUG
なるほど、リークしちゃうんだ。
2024/11/12(火) 00:50:59.75ID:d/AkYtUw
get_mut OR (insert AND get_mut)を
1ステップにまとめるのは気持ち悪いな

1ステップにまとめていいなら
最初からデフォルト値を入れといてもいいのでは?
2024/11/12(火) 02:10:28.31ID:9at7I+bi
>>787
さすが複オジ
ぶっ飛んでるな
2024/11/12(火) 03:23:50.67ID:SFBl6mVs
>>781
この辺のルールかなって思ったけど正直分からん
https://doc.rust-lang.org/reference/destructors.html

return x;をpanic!()に変えるとコンパイル通ってしまうのはどこかに明確な説明があるかね……
2024/11/12(火) 03:24:11.27ID:SFBl6mVs
>>781
drop scopeの決定時に制御フローは考慮されないってことなのかなって思ったけど正直分からなくなってきた
https://doc.rust-lang.org/reference/destructors.html

return x;をpanic!()に変えるとコンパイル通ってしまうのはどこかに明確な説明があるかね……
793デフォルトの名無しさん
垢版 |
2024/11/12(火) 07:26:38.88ID:7hmoxDUg
>>789
複おじの発想が気持ち悪い
2024/11/12(火) 10:15:49.34ID:m541/0mz
>>781
省略せずに書くと
fn do_something<‘a>(&’a mut self) -> &’a mut [u8]

return xするとxのライフタイムは’a
xは&mut self.dataの一部なので&mut self.dataのライフタイムも’a
‘aのライフタイムに渡って&mut self.dataを借りておく必要があると解釈されるので
self.data = Some(vec![0u8; 10]);はエラーになる

マッチしない場合は借りないようにしてくれよと思うのはわかるが
これは今のバージョンのボローチェッカーの制約
nightlyで使える新しいボローチェッカーならエラーにならない

詳しいのは↓ここ
https://rust-lang.github.io/rfcs/2094-nll.html#problem-case-3-conditional-control-flow-across-functions
2024/11/12(火) 10:22:11.79ID:m541/0mz
if self.data.is_some() {
return self.data.as_mut().unwrap();
}

if let Some(ref mut x) = self.data {
return x;
}
でも
エラーにならない
2024/11/12(火) 10:23:41.85ID:m541/0mz
>>793
複おじではないよ
2024/11/12(火) 11:06:54.00ID:POGIqTjB
>>794
新しいボローチェッカーって-Zpolonius=nextのことでいいの?
付けても通らなかったけど、これが通せることを目標にしてるって意味?
2024/11/12(火) 11:26:31.07ID:syNPHnUf
仇討ちして英雄になりたいのか
とんでもねえ話だなこれ
2024/11/12(火) 13:38:59.51ID:DUnFCq7X
>>797
-Z poloniusで通る
2024/11/12(火) 14:07:23.60ID:SFBl6mVs
>>799
おっいけたわありがとう
-Zpolonius=[legacy|next]だと思ってたらいつの間にやらon/offフラグになってたのね
801デフォルトの名無しさん
垢版 |
2024/11/12(火) 18:29:56.22ID:03t9MEqY
>>781
左右の型が一致しない(右だけ参照)この部分を
if let Some(x) = &mut self.data {
昔からの正規にrefを使って左右の型を一致させて
if let Some(ref mut x) = self.data {
こう書けばコンパイル通る点は興味深いな
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況