Rust part24

■ このスレッドは過去ログ倉庫に格納されています
2024/05/27(月) 06:41:26.82ID:T4AFD1f4
公式
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 part23
https://mevius.5ch.net/test/read.cgi/tech/1708677472/
2024/07/12(金) 17:11:30.65ID:LuKbokrL
>>780
サンキュー

>>781
そのあたり全然勉強してない
「相互に参照し合うあうメモリは持てません。それを制限してあまりあるメリットを提供します。どうしてもやりたい人のために別口を用意しました」
という事実が重要
783デフォルトの名無しさん
垢版 |
2024/07/12(金) 20:20:08.14ID:0tYdINiS
Rust製コードエディター「Zed」がLinuxにようやく対応
Windowsサポートにも期待

ttps://forest.watch.impress.co.jp/docs/news/1607906.html
784デフォルトの名無しさん
垢版 |
2024/07/12(金) 20:23:46.34ID:0tYdINiS
個人利用は無償 ~JetBrainsがRust向けIDE「RustRover」を一般公開
メモリ安全性を保障したプログラミング言語「Rust」の開発に特化した統合開発環境

ttps://forest.watch.impress.co.jp/docs/news/1607747.html
2024/07/12(金) 20:46:42.78ID:KyXC0KGT
別口を用意するとは?
RustらしくないRustを用意することかな

もし日本語らしくない日本語が何か成果を出したら
日本語らしさを学習したAIに都合が悪い
2024/07/12(金) 21:35:52.40ID:VV8L6PZC
>>784
慣れの問題なんだろうけど
vscodeがいい…
2024/07/12(金) 22:05:28.85ID:LuKbokrL
>>785
参照カウンタ等がその別口
逆に聞くけど全てを参照カウンタで書かないのはなぜ?
788デフォルトの名無しさん
垢版 |
2024/07/12(金) 22:12:50.70ID:VeLgD+zy
>>781
RcやBoxは分かりやすいけどStringやVecも動的確保だよね、ということに気付いてない人もいるかも?

Rustが良いのはムーブが基本なおかげで意図せぬメモリコピーが起きないこと
所有権を他に渡す (ある構造体から別の構造体にか、あるコンテナから別のコンテナにとか移動する) 際にコストが発生しない
C++は逆で明示的に move しないと意図せぬコピーが起こる
2024/07/12(金) 22:30:09.43ID:KyXC0KGT
>>787
強制されてないから
嫌なら使わなければいい
2024/07/12(金) 22:37:23.69ID:LuKbokrL
電気電子板の人が、Rustの特集やってるインターフェース誌を買って読んだけどわからんかったって言ってたよ
2024/07/12(金) 22:52:07.26ID:LuKbokrL
>>789
俺はそんなことしないよ
全てを参照カウンタなんて使わずに書かない理由を探る
2024/07/12(金) 23:03:04.47ID:IhFaP3QA
>>787
C++で常にshared_ptrを使うと遅い
参照カウンタを利用しがちなSwiftやNimは遅い
2024/07/12(金) 23:08:24.73ID:LuKbokrL
参照カウンタ自体は全然新しくない
Rustがそれを無くせない理由が知りたい
2024/07/12(金) 23:24:14.35ID:LuKbokrL
複数の所有者がいる場合に参照カウンタが有効なのは分かる
難しいのは循環参照
参照カウンタで何が書け、何しか書くべきでないか
795デフォルトの名無しさん
垢版 |
2024/07/12(金) 23:48:00.71ID:VeLgD+zy
>>793
メモリ安全性を提供するため
オブジェクトを共有するのに「所有権は1人だけが持ち、他はそれを参照する」仕組みだと、すでに実体が消えてるオブジェクトを参照する問題が起こり得る
Rustでは、そのようなオブジェクトは参照カウンター付き (RcやArc) にするか、ライフタイムにより「寿命の短いものが寿命の長いものを参照している」ことを示さない限りコンパイルが通らないようにすることで安全性を保証している

逆にC++は参照カウンターなしでも共有できるけど正しく実装しないとメモリ関連のバグを引き起こす
この手のバグはセキュリティの問題になり得る問題を特定しにくい等の厄介さがあるから、Rustはそれをコンパイル時にできる限り防ぐという考え
2024/07/12(金) 23:56:48.21ID:n+FrpY/U
同一スレッド内の別タスクと共有する時にRcを使う
別スレッドや別スレッドになりうる別タスクと共有する時にArcを使う
797デフォルトの名無しさん
垢版 |
2024/07/13(土) 00:02:12.31ID:mV5TIlCk
親子関係のようなオブジェクト間で相互参照するならWeakを使う
これはRcやArcから作るもので、「メインの所有者とそれを弱参照する共有相手」の関係になる
Weak側は相手がまだ存在することを確認できないと参照できないというもの
2024/07/13(土) 00:46:50.81ID:UG7jOJ2R
Rust の所有権システムは機械的に静的検証が可能なように設計されている。
しかし Rust のルールでの機械的静的検証で安全だと確信できないが実際には安全というケースは
ごく普通にあり、その内の典型的なものは実行時のチェックで補えるようにライブラリが整備されている。
2024/07/13(土) 02:23:43.98ID:k/Plwdnm
>>787
全てをRcで扱って渡すときはRcをclone()して渡せばライフタイムを気にしなくて済むが
参照カウンタとその増減のオーバーヘッドだけでなく
書き換えたいなら内部可変性を持ちそのオーバーヘッドも加わるとともに
スタック上で済むときも必ずヒープ利用となるオーバーヘッドもある
2024/07/13(土) 08:49:12.36ID:zzh5ASvo
zennとかqiitaとかのrust記事みてると
活発に描いてた人は2019-2022くらいで
その後更新されてないのが多い
みんな試しただけで使ってないのか
2024/07/13(土) 08:51:48.91ID:zzh5ASvo
>>784
いくつものバージョンのrustやそのバージョン用のcratesを
それぞれ独立に管理して切り替えて使える統合環境なら嬉しいな
venvみたいな
2024/07/13(土) 08:54:10.60ID:zzh5ASvo
>>788
>Rustが良いのはムーブが基本なおかげで意図せぬメモリコピーが起きない

doubt
2024/07/13(土) 08:56:33.88ID:zzh5ASvo
>>790
特集のRustは知らんけど
特集じゃなかったときのインターフェースで紹介されたRustは
(インターフェース誌の読者に多いであろう)C言語利用者に判り易く説明されていた
そういうスタンスだからC知らん人にはきついのかも
2024/07/13(土) 08:58:41.51ID:zzh5ASvo
>>793
無くせない訳じゃなくて
参照カウンタを使わない描き方は今でも充分過ぎるほど可能
特に純粋な関数型言語を使ったことのある人は後者の方が得意だろう
2024/07/13(土) 09:03:05.94ID:UG7jOJ2R
ムーブは管理上の概念で、低レイヤではコピーしてる。
Rust のムーブはカスタマイズの余地なくコピーする (最適化で消えることはある) が C++ のムーブはカスタマイズの余地 (ムーブコンストラクタの定義) があるので効率の面から考えると Rust のほうがよいとは言えない。
2024/07/13(土) 09:29:23.45ID:+smP1Ssu
>>801
venvはないわー
cargoやrustupだけでずっと簡単に管理できる
IDEをそれらをGUIから活用するだけ
2024/07/13(土) 09:38:04.64ID:4hBdJvP4
コマンドプロンプトを無くせない理由を考え続けているそこのあなた
まあいいじゃんそういうの
2024/07/13(土) 09:38:06.14ID:OKewYK0N
>>800
当時記事書いてた一人だけど、日本語書籍も増えたしいまさら書くことないんだよね
アドベントカレンダーがあるならネタ考えるか、くらい
自分はまだRust使ってるし、当時記事書いてた人たちもRust使ってるベンチャーとかに転職してて、だいたいみんな書いてるんじゃないかな
2024/07/13(土) 10:09:47.61ID:aKeOI53x
Rustはカンファレンスとか見てても最近は成熟したからなのか特に目新しいものはない気がする
2024/07/13(土) 10:11:38.51ID:CU8fyG8D
vscodeにできてjetbrains製ideにできないことってある?
正直jetbrainsのヤツのほうがvscodeより使いやすい
2024/07/13(土) 10:27:13.13ID:E2vTTaV1
JetBrains製品は金払ってまで使うほどVSCodeより優れてるわけでないだけで良いIDEではある
VSCodeを何故使うかは商用利用無料だからに尽きるんだわ
2024/07/13(土) 10:59:18.93ID:SqKWY/h6
>>767 >>768
>traitが実装される具体的な型は全てsubtypeに相当する兄弟同士であるため
>supertrait/subtraitの場合に例えばある構造体についてそのインスタンスはどちらも同一になるから
どちらも同じ勘違いをしてるよ
よく読もうね

What is wanted here is something like the following substitution property:
If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T,
the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T
2024/07/13(土) 11:00:31.54ID:l6/BNZgQ
仮にfleetが商用無料になるなら喜んでvscodeを捨てるけど金にがめついjetbrainsが商用無料で配るなんてありえない話
javaやkotlinならともかくrustなら商用無料のvscodeで十分
2024/07/13(土) 11:14:27.08ID:3n/3tOrD
>>812
そこでRustの場合はTがトレイトでSが構造体などの各型で
「impl T for S 」とS型にトレイトTを実装して
「let o1: S = ...」がS型の値(=オブジェクト)になる
『object o1 of type S』 ←存在する
『object o2 of type T』 ←存在しない
したがってRustのトレイトはLSPとなんら関係がない
815デフォルトの名無しさん
垢版 |
2024/07/13(土) 11:36:15.00ID:mV5TIlCk
よく分からんけど
fn do_somethg(x: impl T)
にS型のオブジェクトoを渡すなら、do_somethingにとって o is T が成り立つんじゃない?
この関数は渡された o が S1 なのか S2 なのかは認識しないのだし
2024/07/13(土) 11:44:56.49ID:4Ly9sDTU
>>815
fn foo(x: impl T)は単相化されて
fn foo(x: S1)と
fn foo(x: S2)の二つの関数になるんだよ
いずれにしてもxはS1の値かS2の値であって
Tの値は存在しないね
2024/07/13(土) 11:50:56.55ID:6r0IzkzM
>>813
さすがフリーライダー。
相手に対する敬意が毛ほども無い。
818デフォルトの名無しさん
垢版 |
2024/07/13(土) 11:54:54.91ID:mV5TIlCk
それはコンパイルのされ方の話であって意味の上での問題ではない気がする
Box<dyn T> なら動的ディスパッチされるわけだし
let x: T = ... のような変数を作れないという意味ならその通りだけど、それはオブジェクト指向言語におけるインターフェースでも同じでは
(それともインターフェースに対してLSPは成り立たない?)
2024/07/13(土) 12:02:36.42ID:7b/8td6H
>>812,814,816
なんで毎回飛んでレスするの?
2024/07/13(土) 12:09:19.16ID:Zf2Y/4l2
前も貼ったけどRustはこういうニーズを背負ってる

オブジェクト指向を学ばなかった話
https://qiita.com/adaiimps/items/e04ae03371435aeffe87

C++、ObjectiveC、JavaだったのがRust、LLVM、ELFになって、あーやっぱこっちの方が面白いねと、
好きも嫌いもなく色んな言語を学びまくってる人はLLVMは学ばないのかなと
2024/07/13(土) 12:15:08.95ID:SXOx4oHh
>>818
LSPでは「o1 of type S」と「o2 of type T」の二つのobjectの挙動を比較してるのよ
「o2」が存在しないと挙動の差を論じられないですよ
2024/07/13(土) 12:31:19.55ID:IqeBToeS
rust始めたけどtokioまわりの非同期処理が難しい…
2024/07/13(土) 12:34:40.11ID:UG7jOJ2R
置換原則に沿うかどうかは具体的な実装を検証しないとわからないし、大抵の場合に機械的に検証することは出来ない。
型をサブタイプの関係にするのは原則に沿う「ことにする」という表明になることはあるが、原則に沿うことの保証にはならんのだ。
824デフォルトの名無しさん
垢版 |
2024/07/13(土) 12:40:54.94ID:mV5TIlCk
>>821
>>812 を字義通りに解釈するならそうだけど、その文章はC#やJavaが登場する前の1988年のもので、現在のオブジェクト指向にそのまま適用して良いのか?と思う
インターフェースでない、実体のあるクラスの継承関係についてしか言えなくなるし

現在だとリスコフの置換原則は抽象インターフェースも含んで説明される方が多いように思う
「クラスを継承する際のみに適用できるルール」のように説明されてるのは、少なくとも自分は見たことがない
2024/07/13(土) 12:44:05.69ID:Bid5yHc7
お前らずっと同じ話をループさせてんな😅
2024/07/13(土) 12:51:22.30ID:kEBSnfkM
>>824
親(基底)と子(派生)の挙動の差で満たすべき条件をLSPは挙げてるよね
少なくとも親にも挙動(実装)が存在しないとLSPを満たしているかどうか言及できないと思う
2024/07/13(土) 13:43:19.43ID:4hBdJvP4
>>825
好き嫌いの感覚に素直に従えば面白味のないループはすぐ止まりそうなのに
2024/07/13(土) 13:52:54.97ID:E+PNnzD+
PartialOrd: PartialEqは
PartialEq(等価判定)を持つ型にPartialOrd(半順序判定)を追加するときに
a.partial_cmp(b) == Some(Ordering::Equal)

a.eq(b) (⇔ a == b)
が同じになることを期待してる

この場合の置換の対象は型のインスタンスではなく使われる型の関数だから
LSPをインスタンスの置換に限定するか処理の置換にまで拡張するかで結論が変わる

PartialOrdの追加はPartialEqを使ってる既存のコードに影響しないから
技術的にはLSPと無関係ともいえるし
PartialOrdとPartialEqの等価判定の互換性は概念的にLSPの対象とも考えられる
2024/07/13(土) 14:35:50.27ID:MYuplL5h
つまりRustのトレイトは
LSPの原義に従うと対象外となり
拡張して考えるとLSPを常に満たす
ことになるわけか
830デフォルトの名無しさん
垢版 |
2024/07/13(土) 15:25:32.20ID:mV5TIlCk
>>829
意味の上で考えるとしても「常に」は満たさないかと

struct MyString(String);
impl Clone for MyString {
 fn clone(&self) -> Self {
  Self("元の文字列と関係ない文字列".to_string())
 }
}

のようにすれば、そのトレイトが期待する動作に反した型は作れるわけで
引数や戻り値のシグニチャの同一性だけに注目するならtraitに違反することはできないけど、それなら継承やインタフェースでも同じで、「LSPに違反してはならない」という原則はそもそも意味がない (常に違反できないから) ってことになるし
2024/07/13(土) 15:38:58.70ID:MYuplL5h
>>830
それLSPのどの項目に違反してる?
LSPは振る舞いに関する形式的なものなのでそのような意味論にまでは踏み込んでいないよ
832デフォルトの名無しさん
垢版 |
2024/07/13(土) 15:50:29.46ID:mV5TIlCk
>>831
例えば
fn test_clone(x: impl Clone + PartialEq) {
 assert!(x.clone(), x);
}
はClone および PartialEq トレイトの振る舞いに依存したコードだけど、この振る舞いに反した型は作れるよね
トレイトは事後要件 (x.clone() == x) を定義できないし、そもそも Clone はそれを担保していないと主張することはできるけど、それならLPSって何のためにあるんだ?ってなるし
2024/07/13(土) 15:54:23.34ID:4hBdJvP4
「内在論理」に踏み込めば争いを解決できる説のようなものか
逆効果なのでは?
834デフォルトの名無しさん
垢版 |
2024/07/13(土) 15:55:51.56ID:mV5TIlCk
訂正
>>832 のアサート行は assert!(x.clone(), x) でなく assert!(x.clone() == x)
2024/07/13(土) 15:57:24.24ID:UG7jOJ2R
>>831
不変条件を弱められないルールだろう。
不変条件はシグネチャや定義域で表現できないものも含めた振る舞いの仕様全てのことで、挙動が (仕様に照らして) 望ましくなければ原則を満たさないと言える。
2024/07/13(土) 16:03:55.44ID:E+PNnzD+
829でPartialEq/PartialOrdを例に出したのは
この2つのtraitがsuper/subの関係にあるからで
Cloneとその実装型の関係とは別だよ
PartialEqとPartialOrdの等価判定についてのLSPを考えてる

PartialOrd: PartialEqとする以上
PartialOrdの比較はPartialEqの等価条件を保存すべき←LSP?
みたいな
2024/07/13(土) 16:10:18.20ID:MYuplL5h
>>836
確かにそちらの例は二つのトレイトがsuperとsubの関係だからLSPを満たしてるけど
>>830の例はLSPとは関係ないな
838デフォルトの名無しさん
垢版 |
2024/07/13(土) 17:43:27.19ID:mV5TIlCk
>>831
意味でなく形式に拘るなら「事後要件を弱めてはいけない」などのルールは、要件がプログラム等の形式で表現されない限りLSPの評価の土台にすら上がらないってことにならない?

Cloneトレイトは公式のドキュメントに

// Required method
fn clone(&self) -> Self;
Returns a copy of the value.

とあって、exampleでは実際に assert_eq を使って説明しているので、この説明を元にCloneトレイトを実装する型の妥当性を判断して良いように思う
これでもまだ「それは意味論上のものでしかない」というなら、逆にそれをクリアしてクラス間の振る舞いを示している現実的な例を教えてくれ
2024/07/13(土) 22:57:22.69ID:ZTGyFNne
>>838
それは単純な例だから上手くいってるように思い込めるんじゃないかな
例えばclassの場合はもっと複雑な例になってもsuperclassのコードと挙動が実際にあり
それとsubclassの挙動や(必要なら)コードと照らし合わせて判定できるよ

しかしtraitにはそれがないからドキュメントや付加assertなど一段上のメタ情報を用いなければ何も進めることができない
したがってLSPの枠組みと似てる面はあっても別物
2024/07/14(日) 04:00:15.58ID:xmUtANA3
知らんけど
JavaとかC#の世界でも、interfaceが実装者に要求する条件を実装者が実際には満たさない、って場合にLSP違反って言われるの?
ならRustのtraitでも同じこと言ってよさそうだけど、多分言わんよな
2024/07/14(日) 05:23:41.72ID:QaC7oPd0
継承なしのカプセル化だけなら普通のC言語でもできるし、再コンパイルの問題(変更を加えたファイルだけを再コンパイルすればいいという原則の破れ)も発生しない
それがそのままライブラリやオブジェクトの単位になったんじゃないの
2024/07/14(日) 06:49:30.82ID:ma8dE8UE
文系:xとは未知のもの
厨房:いや未知のものはyやろ
理系:未知のものはfですdf/dx=g(f)を解きます
2024/07/14(日) 07:37:29.94ID:iqWqiKXK
>>841
Rustのtraitにはクラスのような継承はないけど、抽象的なコードを継承できるよ
2024/07/14(日) 07:37:59.13ID:iqWqiKXK
例えばIteratorのtraitにはこのようにfoldメソッドのコードがあって

fn fold<B, F>(mut self, init: B, mut f: F) -> B
where
 Self: Sized,
 F: FnMut(B, Self::Item) -> B,
{
 let mut accum = init;
 while let Some(x) = self.next() {
  accum = f(accum, x);
 }
 accum
}
2024/07/14(日) 07:39:51.02ID:iqWqiKXK
未知のIteratorであっても重複コードを書くことなく自動的にこのfoldメソッドが使える
2024/07/14(日) 07:40:10.97ID:iqWqiKXK
クラスのメソッド継承との決定的な違いは、このコードにメンバー変数は一切登場せず、つまりいかなる構成の型からも独立した抽象的なコードであること
847デフォルトの名無しさん
垢版 |
2024/07/14(日) 09:23:36.10ID:JssLuzWj
fold って next とどうちがうん
848デフォルトの名無しさん
垢版 |
2024/07/14(日) 10:13:20.02ID:aq5pPuoi
>>847
nextはイテレーターを一つ進めるもの、foldやreduceはイテレーターに対して畳み込みを行うもの
例えば「配列内の全ての数値を足し合わせる」とか「全ての数値を掛け算する」「配列内の文字列を全て連結する」いった操作を行うものだよ

この類のものは他の言語でも使われるし、簡潔なコードを書けるようになるから知っておくと良いよ
配列等のコンテナに対して一般に map, filter, reduce と呼ばれる操作があって、そのうちreduceは「要素を畳み込んで1つの値にする」もの
畳み込む方法を関数で渡すもので、概念的には [1, 2, 3].reduce(add) や [1, 2, 3].reduce(multiply) のような形になる
渡す関数は関数のほかクロージャ (言語によってはラムダ式とも) も使える
こんな感じに抽象化するとfor文を使わなくて済むし、何をやってるかが明確になる
2024/07/14(日) 10:32:15.39ID:iqWqiKXK
言語によって呼び名や使い分けが微妙に異なるけど
Rustでは2種類をこう呼び分けています
foldは初期値を別途指定する万能型の畳み込み
reduceは初期値が最初の要素となる畳み込み
2024/07/14(日) 10:33:24.33ID:iqWqiKXK
そして万能型のfoldを呼び出す形で
このような特定の型の構造に依存しない抽象的なコードが
trait Iteratorに用意されているため使えます

fn reduce<F>(mut self, f: F) -> Option<Self::Item>
where
 Self: Sized,
 F: FnMut(Self::Item, Self::Item) -> Self::Item,
{
 let first = self.next()?;
 Some(self.fold(first, f))
}
2024/07/14(日) 11:05:51.89ID:iqWqiKXK
なぜ二種類あるのか?というと
長さ0だと最初の要素すらないため
reduceはOption型が返る特徴があります

例えば和を求める場合でも
長さ0だったらNoneになってほしいならば
reduce(|sum, n: i32| sum + n)

長さ0なら和が0となってほしいならば
fold(0, |sum, n: i32| sum + n)

と使い分けることができます
ちなみに後者はsum()メソッドが用意されています
2024/07/14(日) 11:33:51.37ID:iqWqiKXK
ごめんなさい
>>851で型指定「: i32」の部分は不要です
Iteratorの要素の型に必ず定まります
空配列[]から始めると型指定がどこにもないため横着してそこで指定しちゃったという顛末でした
2024/07/14(日) 12:47:51.97ID:JssLuzWj
>>822
tokio 自体は難しくないけど
cargo test と組み合わせると難しくなる罠
854デフォルトの名無しさん
垢版 |
2024/07/14(日) 12:50:40.22ID:JssLuzWj
>>848
map も reduce も filter も知ってるけど(pythonとかから)
fold は知らんかったd楠
2024/07/14(日) 12:54:55.73ID:JssLuzWj
>>850
python の reduce は初期値を [0] にするのも任意に設定するのも
同じ reduce という名前でいけるのが
Rust だと reduce と fold で使い分ける必要があるということね
Rust が面倒だと言うことは理解した
2024/07/14(日) 13:21:58.79ID:iqWqiKXK
>>855
そういうことではないよ
RustではOption型やResult型でエラーや異常値を含めて正しい状況を値として得られるんだよ
例えば長さ0で初期値なしの時に
Pythonだとエラーだよね
Rustは常に値として返してくれて今回はOption<Self::Item>型
2024/07/14(日) 14:06:11.77ID:CpW1/GRz
>>854
ML 系とか LISP 系の言語ではだいたい reduce や fold は用意されてるね。
ものによっては右側 (シーケンスの終端) から畳み込むとかのバリエーションもある。
2024/07/14(日) 14:15:44.82ID:iqWqiKXK
Rustならrev().fold(...)だね
2024/07/14(日) 15:28:53.80ID:QaC7oPd0
テンプレートが出てきたあたりからC++の勉強をやめたのだけど
これは「型を引数に取ってインスタンス化する」ということでおk?
それがトレイトをまたいだ場合、いつどこで誰が何してるか分からなくなる
ファイルをまたぐインライン関数みたいにソースレベルでなされること?
2024/07/14(日) 16:59:00.63ID:Q38o8Kq2
>>840
JavaとかC#の世界でも、interfaceが実装者に要求する条件を実装者が実際には満たさない、って場合にLSP違反って言われるの?
言われるよ
リスコフ本人が書いたJavaの本にも書いてある
2024/07/14(日) 17:32:49.60ID:Q38o8Kq2
>>839
>ドキュメントや付加assertなど一段上のメタ情報を用いなければ何も進めることができない
一段上のメタ情報であるspecificaitonを使いなさいというのがリスコフの教え
それがBehavioral SubtypingってものでLSPが伝えようとしてる原則だよ
2024/07/14(日) 20:15:07.35ID:QaC7oPd0
ああ、なんだ
クレート=ELFファイルだと思ってたけど違うのね
2024/07/14(日) 23:33:04.31ID:jL63bGYb
もちろんクレートはコンパイルしてELFに出来得る
2024/07/15(月) 00:49:06.25ID:iuOQZB5q
そうかCOFFあかんか。
AIXとかはどうするんだろう?
2024/07/15(月) 01:06:24.34ID:qZQFNGwo
LLVMのバックエンドにCOFFもあるよ
2024/07/15(月) 01:09:28.33ID:RXziJOxB
LLVMの役割
ELFもCOFFもXCOFFもいける
2024/07/15(月) 01:55:53.37ID:S6UfnUI4
>>860-861
なるほどね、本当に特定の言語処理系の型システムの実装が云々というところからは離れたところにある概念なんだ
あえて関連付けるなら、型システムの部分型付け関係がbehavioral subtypingにもなるように定義すべきであると
上位型が具体型であるために暗黙の条件が多数想定される状況では特にLSPを意識すべきだが、それに限定される概念ではないと
2024/07/15(月) 02:35:13.63ID:fmM+TfOR
supertypeの実装がない場合は
LSPの不変条件・事前条件・事後条件などsubtypeの実装と比較しようがなく
LSPの対象になりようがないよね
869デフォルトの名無しさん
垢版 |
2024/07/15(月) 03:42:20.85ID:csp8v2ux
docs.rs の左上のRマーク
今話題のRen4のマークに似てるね
870デフォルトの名無しさん
垢版 |
2024/07/15(月) 09:46:03.12ID:kpV4D65H
コレクションしないんだから狭義には参照カウンタはGCとは言えない。
広義には含めてやってもいいが。
2024/07/15(月) 11:20:28.28ID:qZQFNGwo
ライブラリは.rlibまたは.rmetaで、これもELFやCOFFとは別物
ふむ
872 警備員[Lv.1][新芽]
垢版 |
2024/07/15(月) 11:29:04.89ID:omk2e105
たしかにRマークってRustから周りのやつ外したような感じじゃん
2024/07/15(月) 11:58:24.83ID:K85WsTqt
Ren4のRマークはsans-serifのゴシック体だからRustのロゴとは全然違うだろ
本人のやる気、こだわりのなさをフォントで表現してるんだから
RustのRと一緒にしたら双方に失礼
2024/07/15(月) 13:14:40.10ID:ZO/EZAih
単に好みの問題だけど
ウィルスっぽくて気持ち悪い
好きじゃない
875デフォルトの名無しさん
垢版 |
2024/07/15(月) 14:14:44.43ID:ko+PCaVU
>>874
元々サビ菌がモチーフやからしゃーない
2024/07/15(月) 18:49:44.14ID:GgRIn2WF
独裁者にも見た目がダサい奴がよくいるけど言っても無駄だ
デザインの力とは全然違う別の力でねじ伏せてくる
877デフォルトの名無しさん
垢版 |
2024/07/15(月) 19:16:07.61ID:Vjas5sQD
ダサいという指摘に理由を説明しても、ダサいことは変わらないんだよな
言語がダサければ信者もダサい
うだうだ言いながらダサい服着てそう
2024/07/15(月) 22:03:42.65ID:e+J3OGv0
イテレータ要素をヒープに格納するにはこれでいいんか
.fold(Vec::new(), |mut v, t| { v.push(t); v })
2024/07/15(月) 22:12:32.29ID:S6UfnUI4
またイテレータの話してる
2024/07/15(月) 22:50:12.36ID:9YaXaz6n
>>878
collectしろや
881デフォルトの名無しさん
垢版 |
2024/07/15(月) 23:25:29.58ID:wT4qVw/w
>>878
分かって書いてるかもだけど一応
let v = (0..10).collect::<Vec<i32>>();
コンテナにまとめるならこんな感じに collect を使う
例えば文字を走査するイテレーターをStringにcollectするようなことも可

型パラメーターは推論が効くのでそれに任せても良い
左辺に情報があるならcollectの型パラメーターはいらない
let v: Vec<i32> = (0..10).collect();
要素の型が分かるなら、右辺のコンテナの中身は_で推論させても良い
let v = (0i32..10).collect::<Vec<_>>();
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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