1 名前:デフォルトの名無しさん mailto:sage [2021/06/17(木) 00:24:12.56 ID:NvYoNP9C.net] 公式 https://www.rust-lang.org/ https://blog.rust-lang.org/ https://github.com/rust-lang/rust Web上の実行環境 https://play.rust-lang.org 日本語の情報 https://rust-jp.rs/ ※Rustを学びたい人はまず最初に公式のThe Bookを読むこと https://doc.rust-lang.org/book/ ※C++との比較は専用スレへ C++ vs Rust https://mevius.5ch.net/test/read.cgi/tech/1619219089/ 前スレ Rust part10 https://mevius.5ch.net/test/read.cgi/tech/1617367084/
752 名前:デフォルトの名無しさん [2021/08/19(木) 13:09:24.52 ID:5RRw/fpd.net] >>737 それは強い静的型付けのメリット 異なる型同士の==が通るのは困る といいたいところだけど PartialEqトレイト次第で異なる型でも==してくれる場合もある 文字列など でも整数は厳密でi32とi16ですら不許可
753 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 13:34:53.71 ID:vGJ7k9jZ.net] >>738 でも、上の例で vec0.iter().filter(|&x| x + 0 == 1); が通るのは+0したときに中身がプリミティブ型だから数値だけ取り出してくれてるんでそ?
754 名前:デフォルトの名無しさん [2021/08/19(木) 13:41:52.67 ID:NIu45PdU.net] >>739 それはまた別で>>715 つまり足し算の実装
755 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 14:53:02.41 ID:qnkUxlpG.net] &i32 + i32 の計算ができるようAddトレイトで実装されていて、結果をi32で返すようになってるからエラーにならないってことでしょ?
756 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 14:59:15.22 ID:OmSSsNQv.net] >>741 そのとぉーり!
757 名前:デフォルトの名無しさん [2021/08/19(木) 15:34:51.11 ID:SriMwJau.net] >>741 ご丁寧にi32+i32 i32+&i32 &i32+i32 &i32+&i32の4種類をカバーしてくれてるね &&i32はサポートしていないため vec0.iter().filter(|x| x+1==2)はコンパイルエラー
758 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 16:37:43.70 ID:gHMNbMrQ.net] まず>>715 の間違いを反省しようね >let a = 99; >let c = &&a; >assert_eq!(100, *c + 1); // &i32は参照外してi32でOK
759 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 16:44:47.80 ID:hQY8lbBV.net] >>744 それであってるぜ &i32+i32は左だけ参照を外してi32にして足し算する
760 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 17:44:32.43 ID:t/I60tUF.net] そりゃ当たり前だろw とことんダメなやつだな
761 名前:デフォルトの名無しさん [2021/08/19(木) 18:58:02.70 ID:58T7qCMn.net] >>733 >>734 丁寧に教えてくれて、ほんとありがとう
762 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 21:41:29.08 ID:vGJ7k9jZ.net] >>743 なるほど、なんかすべての挙動を把握しないとならないんだね でも、やっぱり「&1」が通用するのは納得いかない(´・ω・`)
763 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 22:05:30.35 ID:RF3Q0l8Y.net] >>748 基本的には正しく型を用いれば済む &i32は数値ではなく数値への参照にすぎない *付けなくても済む便宜の恩恵を受けるのはよいけどそれを理解したうえでしているかどうかの違い
764 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 22:29:20.97 ID:c562wt5h.net] String と &str が == で比較できるなら i32 と &i32 も比較できて良い気はする 単に impl がないだけだから pull req 送ったら取り込んで貰えるのでは
765 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 22:55:59.39 ID:vGJ7k9jZ.net] もう純粋に&1て、1の参照じゃんね その意味がわからんし、存在意義がわからん 変数同士ならわかるけど、定数的に書いてるんだったらもうプリミティブ型だったら 中身で判断してくれよヽ(`Д´)ノウワァァァン
766 名前:デフォルトの名無しさん [2021/08/19(木) 23:28:13.13 ID:2mmZi2HD.net] >>750 今もi32と&i32の組み合わせ4通り定義 そこへ&&i32が加わると9通り定義 そこまでする意義は? >>751 だからx==&1ではなくて素直に*x==1と書こう
767 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 23:48:19.67 ID:k/U3ouxt.net] >>751 プリミティブのwrapper crateを作って自分の好きなように定義すれば万事解決
768 名前:デフォルトの名無しさん mailto:sage [2021/08/19(木) 23:58:39.37 ID:A1SUdzrU
] [ここ壊れてます]
769 名前:.net mailto: そういや&1みたいなのって実際に使う場面あるの? [] [ここ壊れてます]
770 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 00:03:22.90 ID:o+L+NM8T.net] 推奨する方法をやりやすく、推奨しない方法をやりにくく Rustは他の言語に比べると特に後者についてよく考えられてる
771 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 00:07:53.98 ID:iQK+FWFq.net] >>754 postgresクレートのquery()でparamsに数字を書きたいときとか pub fn query<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<Vec<Row>, Error> where T: ?Sized + ToStatement
772 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 01:09:30.92 ID:W7hoDzmL.net] >>752 *x == 1 と書けというのは分かるんだけど impl PartialEq<String> for &str や impl Add<&i32> for i32 があるのに impl PartialEq<&i32> for i32がないのは一貫性がないように思う なんで実装されていないのだろうか
773 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 01:11:40.00 ID:W7hoDzmL.net] >>757 自己解決 RFC1332で議論されていた
774 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 01:12:10.07 ID:hEbF/PXF.net] rubyもpythonも見よう見まねで書けるんだけどなー javaなんてC++とほとんど同じだから半日もあればマスターできる でもrustだけは勉強しないと無理っぽい 難しいよ
775 名前:デフォルトの名無しさん [2021/08/20(金) 01:34:49.41 ID:qcewwL/9.net] >>757 実は整数と文字列ではそこの逆転現象が起きていて Stringと&strの等号比較はOK assert!("xyz".to_string() == "xyz") しかしStringをmatch文でアームに&strだとコンパイル型エラーでNG // assert!(match "xyz".to_string() { "xyz" => true, _ => false, }); &i32とi32の等号比較はコンパイル型エラーでNG // assert!(&123 == 123); しかし&i32をmatch文でアームにi32だと比較OK assert!(match &123 { 123 => true, _ => false, });
776 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 01:38:48.16 ID:omEK/Sui.net] オブジェクトの同一性 (メモリ上の同一の場所に配置されている) を判定したいときって 参照を == で比較しても駄目ですよね? ポインタを取り出すのも恰好が悪いように思うんですが、 なんか定番の方法ってあります?
777 名前:デフォルトの名無しさん [2021/08/20(金) 01:44:35.28 ID:qcewwL/9.net] >>754 消費(ムーブ)せずに参照で済ませるためにiter()を使うと当然 &1 が出てくる let vec0 = vec![1, 2, 3, 4, 5, 6]; assert_eq!(Some(&1), vec0.iter().next()); assert_eq!(Some(1), vec0.into_iter().next()); これはVecだから消費するinto_iter()が使えば 1 に出来るけど スライスだと消費という概念がないから必ず &1 が出てきてしまう
778 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 01:55:55.02 ID:jENR+46K.net] >>761 Rustは所有権があるから同一メモリを指すのは所有権を持つものへの参照同士かな つまりコード上明白であり比較する必要性がないことに?
779 名前:デフォルトの名無しさん [2021/08/20(金) 02:30:09.57 ID:qcewwL/9.net] こういうことかな 複数の参照もmut参照も生ポインタも当然すべて同じアドレスを指している let mut i = 123; let pi1 = &i; let pi2 = &i; println!("{:p}", pi1); // 0x7fffebf915a4 println!("{:p}", pi2); // 0x7fffebf915a4 let pi3 = &mut i; println!("{:p}", pi3); // 0x7fffebf915a4 let rpi3r = pi3 as *mut i32; // 生ポインタ println!("{:p}", rpi3); // 0x7fffebf915a4 生ポインタを使って書き換えると元の変数が書き換わるので確かにこれは変数の格納アドレス unsafe { println!("{}", *rpi3); // 123 *rpi3 = 456; } println!("{}", i); // 456
780 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 02:32:13.12 ID:0J8On0UY.net] ptr::eqで
781 名前:デフォルトの名無しさん [2021/08/20(金) 10:16:46.67 ID:Z3M3k8Ob.net] メンテナンス性最悪の自己満足オナニー言語
782 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 11:41:07.99 ID:0Iuc7w1s.net] >>766 それは逆 メンテナンス性は最も優れているプログラミング言語の一つ
783 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 13:42:55.60 ID:ZqTwz4dI.net] ポインタ関連の問題が所有権と参照で絶対に発生しないってのはデカイよね
784 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 13:59:09.33 ID:lR6AxyIv.net] 将来の苦痛を先に解消できるのが良いのにな、不具合も絞り込みやすい メンテナンス性悪いってどの辺言ってんのか聞いてみたい
785 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 14:18:54.33 ID:nkJxp5PO.net] 一年ぶりに触るソースを大規模改修しても、コンパイル通せばほぼ動く安心感ある 他言語(特に動的型言語)だと相当テストを作り込まない限り、このメンテナンス性は得られない印象
786 名前:デフォルトの名無しさん [2021/08/20(金) 14:28:37.40 ID:y1HLeTwS.net] データ設計を少し考えさせられることによって メモリ安全性を得ただけでなく見通しも良くなったw
787 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 15:07:52.58 ID:No4kn/Ah.net] 潜在的にバグの原因となる変数の扱いすると コンパイラが怒るのは安心できる
788 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 15:24:51.42 ID:W7hoDzmL.net] >>768 絶対に発生しないは言い過ぎ
789 名前:デフォルトの名無しさん [2021/08/20(金) 15:31:54.88 ID:sJeXN42B.net] 繰り返しでiter()を使ったりinto_iter()を使ったり、ループを使ったり、高階を使ったり。。 そして文字列が複数あったり、更にそれをマクロにされると、それで書き直しが必要だったり 多くの言語でも初心者と上級者で当然、コードの美麗さに違いが出るが余りにも差があり過ぎ たった「一年ぶり」でコンパイルが通らない言語なんてあるだろうけど、そんな話じゃない
790 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 16:06:16.17 ID:c/gVhnyt.net] イテレータなんてどの言語にもあるし困るようなことか? 無理やり導入で汚い言語よりもRustは綺麗に洗練されていて書きやすい
791 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 16:12:21.41 ID:BL1Grv4c.net] 同じようなことなのに人によって書き方が全然違うからクソって言いたいんじゃないの?
792 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 17:10:02.79 ID:H8grjHSU.net] 何が何故問題なのか説明できないイチャモンなんかほっとけ
793 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 20:06:41.30 ID:W7hoDzmL.net] 文字列が複数種類あることが嬉しい人のための言語 嬉しくない人は別の言語を使うべき
794 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 20:28:27.92 ID:TearUC8B.net] >>778 例えばいわゆるスクリプト言語などはいずれもRustのString型相当のものしかないため非効率でメモリ食い散らかす状態になっていますね Rustはそれに加えて部分を指し示すだけの文字列スライス&str型を持っているので無駄なアロケーションを防いで効率の良いコードを書けるようになっていますね
795 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 21:05:31.52 ID:ma1oO0u7.net] >>774 > 繰り返しでiter()を使ったりinto_iter()を使ったり、ループを使ったり、高階を使ったり。 あなたはちょっと無知すぎます。 まず高階関数とも言われるmap()やfilter()等を用いるにはイテレータが必須ですから同じことを指しています。 どちらかを選ぶようなものではありません。 次にRustのforループもイテレータ必須で内部でイテレータを作ってforループを回していますから同じことです。 forループ方式と高階関数方式の2種類で書けてしまうじゃないか!と言いたいのでしょうが、これは他のプログラミング言語でも同じで2種類あります。
796 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 21:07:42.14 ID:EDzGRqES.net] 内包表記なる書き方がある言語もあるらしいねw
797 名前:デフォルトの名無しさん [2021/08/20(金) 21:38:29.08 ID:6XnQ3Oqv.net] 繰り返しでiter()を使ったりinto_iter()を使ったりと複数のやり方があるのはおかしいとの御指摘だが into_iter()は値のイテレータ iter()は参照のイテレータ 同じものに対して適用しても別のイテレータが得られる
798 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 21:47:24.73 ID:pKmgqbo7.net] 少し前までは荒らし以外は結構いいスレだったが 近頃はC++スレでダベってた暇人たちが引っ越して来ちゃってゴミスレ化しつつあるね
799 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 22:24:24.81 ID:ZqTwz4dI.net] >>782 これ、同じメソッドにするのではなくて、イテレータにするのはiter()で共通にして、 参照する場合には、別のメソッドにしたほうがいいんじゃないのかなと思う 例えば iter() ← 値 iter().ref() ← 参照 とか
800 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 22:50:20.88 ID:hEbF/PXF.net] なんで配列にイテレータないんや! 配列を使うな! vecを使えということなのか そういえばC++でもvector使えとか言われてたな もっと配列にも愛を! ところでvecより配列の方がうれしいことってある? 実は配列いらない子なんじゃないかと思い始めた
801 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:02:42.83 ID:Dd/EBaxX.net] >>784 それはiterのシグネチャがメソッドチェーンするかどうかで変わってしまうから 今のRustの型システムでは表現不能だと思う プログラマ視点でも、後続する関数呼び出しがその手前に影響するってのはかなりわかりにくいのでは?
802 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:22:41.88 ID:tipMusVW.net] >>785 スタックとかヒープとかアロケーションとか気にならない用途ならRust使わなくてもいいと思うの
803 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:47:01.90 ID:Omw4vOgK.net] >>786 moveをデフォルトにするのは無理だけど iter()は参照でiter().into()で値ならCow的なのでなんとかなる気がする
804 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:47:19.51 ID:iQK+FWFq.net] >>785 > Rust 1.53からは配列型に対して直接IntoIteratorトレイトが実装されるようになり、配列をそのままループに使うことが出来るようになりました。 https://tech-blog.optim.co.jp/entry/2021/06/18/080000
805 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:54:51.56 ID:hEbF/PXF.net] >>787 いやいや、もちろん配列との比較なんだから、アロケーションの発生しない処理の話だよ スタックを気にするなら、むしろヒープに置いた方がいいし (キャッシュミスヒットの話じゃなくて、スタックオーバーフローの話ね)
806 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:55:03.84 ID:Dd/EBaxX.net] >>788 それだとinto_iterとは意味変わっちゃってるのでは intoで元のコレクションのコピーが作られて、それをイテレートするってことでしょ? コピーを作らず所有権を奪って値をイテレートする方法がなくなってしまう
807 名前:デフォルトの名無しさん mailto:sage [2021/08/20(金) 23:56:59.11 ID:hEbF/PXF.net] >>789 おお! 知らなかった。 ってかめっちゃ最近じゃん! 追いかけるの大変だな
808 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 01:58:33.16 ID:kcBD0DB/.net] >>784 iter().cloned() とか使えば良いのでは
809 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 05:48:08.14 ID:lXSuJ2vU.net] hoge.iter()だと参照でhoge.iter().fuga()だとhogeの所有権ぶんどる、みたいなのは無理な気がする
810 名前:デフォルトの名無しさん [2021/08/21(土) 06:24:06.23 ID:kvS3AY0X.net] >>790 Vecは可変長なので必ずヒープからアロケーションが発生します 一方で配列は必ず固定長でスタックに置かれます >>784 (&vec0).into_iter()はvec0.iter()となるので into_iter()だけにすることも出来なくはないと思いますが 書き方が面倒なので簡潔なiter()と共存してるのだと思います
811 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 09:34:58.66 ID:v7gED8U+.net] >>791 Cow使えばできるという話じゃないよ lazyに所有権を取得するような機能を持った型を追加すれば 今の型システムでも表現できないってことはないんじゃないかって話 そういう型を追加することを型システムの変更と言うのであれば 今の型システムでは表現できないてのに同意するよ
812 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 09:43:26.29 ID:KTz5aeQ/.net] >>795 アロケーションが発生するのは伸長するときだけでしょ 伸長するような用途だったら、そもそも配列使えないし >一方で配列は必ず固定長でスタックに置かれます だめじゃん。スタックオーバーフロー考慮するならvecの方がいいじゃん まあ、自分も組み込み以外でスタックフレームのサイズなんて考慮したことないけど
813 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 09:50:40.59 ID:KTz5aeQ/.net] >>795 ちなみにスタックにあることによってL2キャッシュに載りやすいだろ! という意見ならそれは同意する。サイズが小さければね。
814 名前:デフォルトの名無しさん [2021/08/21(土) 10:08:08.47 ID:/0ZvMIRv.net] >>797 > アロケーションが発生するのは伸長するときだけでしょ いいえ。 Vecの実体は必ずヒープにアロケーションされます。 Vec自体は(指定しなければ)スタック上で、ヒープへのポインタや長さなどで構成されて固定長です。 Stringも内部はVec<u8>なので同様です。
815 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 10:12:53.88 ID:KTz5aeQ/.net] >>799 ああ、アロケーションじゃなくてヒープにってところを問題視してる? ガベージコレクションの発生を懸念してる?
816 名前:デフォルトの名無しさん [2021/08/21(土) 10:22:22.66 ID:HwKH2mPW.net] >>800 Rustではガベージコレクションは起きない しかしスタック上かヒープ上かの区別は重要 スタック上のデータはその関数を終える時に消滅する
817 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 10:31:43.28 ID:KTz5aeQ/.net] >>801 >Rustではガベージコレクションは起きない ヒープを使ってるんだから起きないわけないだろ >スタック上のデータはその関数を終える時に消滅する Vecの中身だって関数を終えるときに解放されるでしょ されないんだっけ? そもそもの話は配列を使ってるところをVecにしても問題なくね?ってことなんだけど どこが問題になるかの例を示してもらえたら、わかりやすい
818 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 10:58:14.92 ID:Hi//C77Q.net] rustにはガベージコレクションがないんだぜ・・・
819 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 11:04:35.75 ID:eqU3IJp1.net] デストラクタ的な機構で後始末するのはガベージコレクションとは普通言わない
820 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 11:09:11.24 ID:JLDZmydZ.net] Cでもひーぷをつかうとがべーじこれくしょんがおきるの?
821 名前:デフォルトの名無しさん [2021/08/21(土) 11:11:34.22 ID:6mCMrQuL.net] ヒープへのメモリアロケーションはコストが高いから避けたいんでしょ
822 名前:デフォルトの名無しさん [2021/08/21(土) 11:25:28.41 ID:ozkLLafu.net] >>802 RustにGCはない Vecの中身(配列相当部分)はスタック上ではなくヒープ上なので関数を終えるときに解放されない Vec自体が消える時に解放される Vec自体(ポインタと長さなど)はスタック上にあれば関数を終える時に消える もちろんVec自体を関数の返り値として返すことは出来る 受け取った上位の関数でVecの中身を使える 例えば fn main() { let mut v: Vec<i32> = make_i32_vec_from_args(); v.push(999); println!("{:?}", v); } fn make_i32_vec_from_args() -> Vec<i32> { let mut v = Vec::new(); std::env::args().skip(1).map(|s| s.parse::<i32>().unwrap()).for_each(|n| v.push(n)); v } $ cargo run 111 222 333 [111, 222, 333, 999]
823 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 11:42:53.96 ID:3jqa2oM2.net] そういや何でalloca()無いの?
824 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 12:23:12.36 ID:kcBD0DB/.net] >>795 Box<[T; N]> のように配列がヒープに置かれる場合もある
825 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 12:35:23.13 ID:5zDPvhJy.net] >>809 それはBoxだからであって、そんなこと言い出したら整数だってヒープに置かれうる しかし普通に「整数型はスタックに置かれる」と言われる時は、Boxを使わない場合を意味している Boxを使えばヒープに置かれるのは自明だからだ したがって、整数や配列やVecの管理データ部分はそのままだとスタックに置かれるがVecのデータ実体は常にヒープに置かれる、で良い
826 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 13:25:00.39 ID:KTz5aeQ/.net] うーん、なんだかなー みんなヒープのことを無限にバイトを吐き出す魔法の箱かなんかだと思ってない? >>805 >Cでもひーぷをつかうとがべーじこれくしょんがおきるの? 当然 Cのmalloc/freeやC++のnew/deleteでもガベージコレクションは発生する wikipediaの「ヒープ領域」がよくまとってるよ いくつかの理由からfree/deleteのガベージコレクションはJavaやC#のガベージコレクションよりも超高速だ それでも、組み込みの世界ではガベージコレクションのせいでリアルタイム性が失われることを嫌がって、 ヒープを使わなかったりする じゃあ、組み込みでは動的なメモリをどうするかっていうと、リンクドリストのノードをメモリブロックに 見立てて、メモリ管理システムにしたりする これだと取得も解放も定数時間のコストだからね >>807 すまん、例をみてますます配列なくても困らない気がしてきた 配列でできて、Vecにできないことはないの?
827 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 13:35:03.05 ID:+9L1DmAB.net] >>811 Rustにはガベージコレクションはありません おっしゃる通りヒープからの取得も解放も定数時間のコストで行なわれ更にガベージが溜まることはありません Rustでは生存期間や所有権に貸し借りが明白になっているため、使用中のものが解放されたり、解放済みが使われたり、使用済みが解放されなかったりは起きません
828 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 13:50:09.86 ID:KTz5aeQ/.net] >>812 >ヒープからの取得も解放も定数時間のコストで行なわれ これってどういう原理? 本当に定数ならそれもうヒープじゃないんじゃ ヒープツリーを辿る処理も未使用ノードを結合する処理も定数時間って ありえないと思うんだけど
829 名前:デフォルトの名無しさん [2021/08/21(土) 14:16:15.10 ID:G8x/1s0B.net] もしかしてmalloc/freeのヒープメモリ管理のことをこの人はガベージコレクションと呼んでいるのかも そのためRustにガベージコレクションがないことを理解できていないような感じ?
830 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:22:08.01 ID:KTz5aeQ/.net] 調べた ・rustのヒープはフリーリストアロケータじゃない (サイズごとのメモリスラブをさらに分割して使う) ・取得・解放は定数時間じゃない (メモリスラブ全体が未使用になったときに、デフラグして別サイズのスラブとして利用可能になる) →これ実質ガベージコレクション処理じゃん ・当然デフラグは発生するが、大して問題にならない →そうだろうね。C++でさえアロケータ書いたことない ・問題になるならアロケータを自作することも可能(デフォルトはjemalloc) だそうだ。 ヒープはヒープ構造じゃないのか……
831 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:36:21.13 ID:KTz5aeQ/.net] >>814 >もしかしてmalloc/freeのヒープメモリ管理のことをこの人はガベージコレクションと呼んでいるのかも freeの中にもガベージコレクション処理があるんだよという話 javaと違ってマーク&スイープ処理いらないから早いけどね >そのためRustにガベージコレクションがないことを理解できていないような感じ? そんなことはわかってる 今は処理コストの話をしてる サイズが変わらないVecと配列(配列なのでもちろん固定長)でそこまで優位の差があるのかと訊いた そこでVecはヒープを使う(からダメだ)という答えが返ってきたので、 ヒープを使うとなぜダメなんだ? ガベージコレクションのオーバーヘッドを気にしてるのか?と そうするとrustはガベージコレクションありませんと言われた じゃあ、結局のところヒープを使うとなぜダメなんだ?
832 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:43:58.08 ID:3jqa2oM2.net] 勝手に定義した「ガベージコレクション」なんか議論するだけ時間の無駄
833 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:48:02.99 ID:HlQuVij0.net] >>816 あなたが完全に間違っている それを世間ではガベージコレクションとは呼ばない
834 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:50:34.09 ID:KTz5aeQ/.net] >>818 辞書が絶対とは言いたくないがwikipediaの「ヒープ領域」見て
835 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:52:48.65 ID:Hi//C77Q.net] 自分でfreeしたものをGCと呼ぶとは強者が現れたな
836 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:53:06.41 ID:O7+p4qIy.net] それこそwikipediaの「ガベージコレクション」見てもらった方がいいのでは。
837 名前:デフォルトの名無しさん [2021/08/21(土) 14:53:37.02 ID:6mCMrQuL.net] もうジェマロクはデフォルトじゃないよ
838 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 14:58:27.12 ID:Hi//C77Q.net] そういやこんな記事があったよ 実装言語を「Go」から「Rust」に変更、ゲーマー向けチャットアプリ「Discord」の課題とは ttps://atmarkit.itmedia.co.jp/ait/articles/2002/10/news038.html > 平均すれば高速に動作していたものの、数分ごとに平均応答時間が急に大きくなり、 > ユーザーエクスペリエンスを損なっていた。調査したところ、 > これはGoの中核機能であるメモリモデルとガベージコレクタ(GC)に起因することが分かった。 > Rustではガベージコレクションが不要だ。 > 同社がRead StatesサービスをRustで実装しようと考えたのはこれが理由だ。 > Rustを使えば、Goで実装した場合に生じた平均応答時間の急増は見られないだろう。
839 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 15:02:21.85 ID:KTz5aeQ/.net] >>820 だから、ここではコストの話をしてるんだって言ってんのに >>821 見た。もちろん知ってる。 本題からずれてる。自動解放とかデフラグの定義の話がしたいんじゃない 配列とVecのことが知りたいんだって なんだってこう話を逸らすんだ?
840 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 15:02:56.01 ID:watXYiN6.net] >>819 https://ja.wikipedia.org/wiki/%E3%83%8E%E3%83%BC%E3%83%88:%E3%83%92%E3%83%BC%E3%83%97%E9%A0%98%E5%9F%9F > 7月15日(土)12:22の版で記述いただいた内容のうち、「ガベージコレクション」という部分だけ誤りと思われるので、7月19日(水)02:32の版で消させていただきました せやな。
841 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 15:10:24.32 ID:hSZ/tOwO.net] >>824 まずはプログラミング言語におけるガベージコレクションとは何かを理解して 次にRustではそのガベージコレクションがないことを理解して その上で何を質問したいのかを整理してはいかがでしょうか? それを終えてからでないとあなただけ用語の定義が異なったままでは話が進みません
842 名前:デフォルトの名無しさん [2021/08/21(土) 15:10:57.04 ID:IZ1Oj5x4.net] ガベコレは普通javaとかpyのコンパイラやらインタプリタがreference counterをオブジェクトに勝手に付随させる事を想定するけどな Vec arr処理コストの違いに関してはbuffer使わないんだからarrayの方が基本的には糞みたいに早いと思うがな そこらosとかによって最適化図られるからオブジェクト生成のとき以外は決定的な違いあんまなさそうだが 要素数をコンパイルタイムに決定(これのアルゴにもよるが)出来るなら普通はシンプル配列の方が速いよね goはparallel threadingみたいな部分で変なgc実装してて大量に独立の計算量ハード問題導入するからねそこらへんがドイヒーなんだろうな 俺は好きだけど(´・ω・`)
843 名前:デフォルトの名無しさん [2021/08/21(土) 16:18:04.16 ID:iwjgeVKb.net] >>824 何度も説明されている通り 配列は固定長なのでデータ管理部分はなく配列は通常スタック上 Vecは可変長なのでデータ管理部分がありそれは通常スタック上そして配列相当部分は常にヒープ上
844 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 16:29:59.01 ID:0b1Dm8dh.net] コンパクションとガベージコレクションの区別がついてない 世の中のガベージコレクターがコンパクションもやってるからといって コンパクションのみを指してガベージコレクションとは呼ばない
845 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 16:33:27.85 ID:Ay6lvOn8.net] ふりだしに戻る >>787
846 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 16:37:39.49 ID:KTz5aeQ/.net] >>828 それの何が問題? stringの実装はヒープだけど問題ないよね? こういう使い方をすると配列より100倍くらい遅いとか、メモリリークするからVec止めて配列使えとか そういう注意点ある? もちろんループの中でVec::newするとオーバーヘッドでかいとか、 そういうわざとらしいのはなしにして あえていうなら初期化の記述量がちょっと増える、とか?
847 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 16:59:15.86 ID:dJkGQ7Qm.net] >>831 誰も何も問題にしていませんよ あなたが勘違いをして勝手な何かを問題にしているだけ StringはVecにstructの皮を被せただけなので状況は同じ
848 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 17:06:03.36 ID:Hi//C77Q.net] >>829 HDDの頃はよく使ってたHDD最適化と容量を増やすみたいなソフトを思い出した HDDのデフラグ → メモリコンパクション HDDにある不要なキャッシュの削除 → ガベージコレクション こんな感じに似てるな
849 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 17:16:16.64 ID:eqU3IJp1.net] ヒープがヒープ構造じゃないのかとか言ってるから本当に何も知らなかったのだろう オレオレ用語使われると混乱するからとりあえずmalloc動画くらいみて勉強してきてほしい
850 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 17:26:30.08 ID:KTz5aeQ/.net] >>834 そこ話の本筋じゃないんだよなー Vecはヒープ使ってるからダメって言われて、何がダメか説明してくれって言ってるだけなんだけどなー
851 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 17:30:07.73 ID:pF+sRbnf.net] >>835 ヒープ使ってるからダメ、なんて誰も言っていない 全ては君の勘違い
852 名前:デフォルトの名無しさん mailto:sage [2021/08/21(土) 17:31:33.62 ID:KTz5aeQ/.net] >>836 そうなの? じゃあ結論として配列はVecに置き換えても問題ないってこと?