Rust part20

レス数が900を超えています。1000を超えると表示できなくなるよ。
2023/03/03(金) 00:45:28.73ID:vTVY069B
公式
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 part19
https://mevius.5ch.net/test/read.cgi/tech/1673926892/

ワッチョイスレ
プログラミング言語 Rust 4【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1514107621/
2023/07/22(土) 17:07:41.36ID:2BLjTz4O
>>806
コンパクションをするかしないかは独立した問題
マークアンドスイープ自体はコンパクションを伴わない
2023/07/22(土) 17:59:22.96ID:QLIAp4G5
>>807
再配置できないならそもそも論外なんだから
無関係ではないだろ。
2023/07/22(土) 18:05:22.75ID:YLqzZrt5
そういえば君らのメモリ管理の会話でLinkedListの使い道思い出したわ
Rustやその他の言語側じゃなくてOS側のメモリ管理にLinkedList使われてるわ
2023/07/22(土) 18:42:28.71ID:2BLjTz4O
>>808
再配置するのはコピーGCで使用中データ全移動と全ポインタ書き換えとなる
マークアンドスイープGCはその名の通り使用中を辿りマーク付けしてマークされなかったものを再び未使用領域とする
811デフォルトの名無しさん
垢版 |
2023/07/22(土) 19:01:55.55ID:TsQs+vXV
>>807
論点は”一般的”にやってるかどうかだろ
君は一般的にやってないと言ってるわけで
JavaもC#もJavaScriptもみんなGCでcompactionやってる
2023/07/22(土) 19:18:33.46ID:2BLjTz4O
>>811
compactionをする前にマークアンドスイープGC自体は既に終わっていて独立した別の行為
実際にそれら言語では世代別GCが行われていていて新入り若手のオブジェクトはコピーGCを行なうが古いオブジェクトはマークアンドスイープのみで再配置しない方法が一般的
2023/07/22(土) 19:31:27.25ID:nB6v7J6K
隔離スレ行けアスペジジー
2023/07/22(土) 20:04:44.58ID:2BLjTz4O
再配置はデータコピーとそこへのポインタ全て書き換えでコストが大きすぎるから可能な限り避けるのが正しい
世代別GCで若手オブジェクトだけに限ってコピーGCの対象にするのも若手の大半は一時的利用でコピーしなくて済むため

Rustではそんなコストをかけないだけでなくヒープ確保解放のコストすら減らすことと一石二鳥で解決する方法も取られている
例えばbumpalo crateはまとまった領域を持って追記していくだけで個別の解放コストゼロ(=何もしない)と個別の確保コストも最小(=追記のみor足りないとまとまったお代わり)のアリーナアロケータ
つまり未使用領域の再利用をしないことで管理不要となり最高速になるとともにまとめて一気に最高速で返す
具体的にはサーバーまたはバッチ処理で各対象固有データのみそこから確保してその対象を終える時に破棄
これはフラグメンテーションを防ぐのに非常に効果的な方法
815デフォルトの名無しさん
垢版 |
2023/07/22(土) 21:33:49.24ID:kHWj4RWJ
まーた複オジが知ったかぶりして無知晒してるw
初心者かなww
816デフォルトの名無しさん
垢版 |
2023/07/22(土) 22:04:25.70ID:kdu4dn9d
Rust使うくらいならJavaかC#で良いのでは?
2023/07/22(土) 22:08:51.83ID:wR/xGD2g
RustとC#だとどっちがいいの?
2023/07/23(日) 02:44:41.28ID:lmJrnSr9
>>814
GCのないRustが速いわけだ
2023/07/23(日) 11:09:10.60ID:kMNWXVHy
>>814
C/C++でも同じアルゴリズムのアロケータあるで
2023/07/23(日) 11:10:16.97ID:dOw1chPf
>>816
🤮
2023/07/25(火) 06:32:45.09ID:7X7HwnNv
>>819
言語に関係なくそこへ行き着くんだよな
もちろん通常はフラグメンテーションなんか気にせずに普通にコードを書けばよく
稼働時間の長いプロセスでフラグメンテーションが実際に起きた時の解決策の一つ
2023/07/27(木) 13:16:19.02ID:/bGsBsBb
play-rustのコードのコピペのやり方教えて下さい
具体的にはお題スレの

https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=f627f3a5de4a0c467f015a8b1527c141

のコードコピペする方法がわかりません
よろしくお願いします
2023/07/27(木) 14:04:04.46ID:90/I2Z5n
rustは型推論をしてくれると聞いたのですけど、結果どういう型になったか調べる方法はありますか?
Haskellのghciの:tに当たるやつです
例えはghci内で
prelude> let f n = sum [ x^n | x<- [1..5] ]
として
prelude> :t f
とすれば
( Num a, Integral b ) => b -> a
のように返してくれます
rustでコンパイラの型推論の結果どういう型に決定したのか調べる方法はありますか?
2023/07/27(木) 14:28:57.60ID:p+3LvAw4
>>823
LSP 対応のエディタ (VSCode など) を使ってるならそのへんにカーソルを合わせるだけで型は見れるよ。
2023/07/27(木) 21:59:53.82ID:x4QyUuiY
>>823
安直な方法としては関数の戻り型なら -> i32と嘘の型宣言を指定すれば型不一致で正しい具体型をコンパイルエラーに表示してくれる
プログラムで表示したいならこれ
fn get_type<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
2023/07/27(木) 23:11:30.70ID:sTDTKxns
>>824
>>825
あざっす
2023/07/27(木) 23:12:33.60ID:paov2RlH
rustの型推論って曖昧なことを許容したっけ?
すべて一意にならないとならないと思ってたけど
2023/07/28(金) 19:39:32.86ID:4cjf/6GX
>>827
正しい
ジェネリックであってもパラメタは各々で必ず一意に静的に確定せねばならず
impl Traitで型宣言しても各々で一意に具体的な型に静的に確定する
特にそれが関数の引数ならば生成コードは単相化される

ただしdyn Traitはそれらが静的ではなく実行時のオブジェクト生成毎に個別に一意の具体的な型に確定する点で異なる
コンパイル時の静的な生成コードは複数の型で共有となるためvtableを持って対処している
2023/07/29(土) 16:54:29.41ID:Nh9kevR9
なるほど
Rustは最終的にコンパイルが終わって型が完全に推論が終わって単相型が決定した状態でしかわからないのかな
当然get_typeで得られるstrは推論終わって単相型が割り当てられた後の型しかわからないんやな
2023/07/29(土) 18:53:43.03ID:nTghkNr5
コードを書いた時点で型は決まるし書いた人は型を把握できる
ジェネリックな関数だとしても型パラメタ以外の部分は確定している
その関数を呼び出す側が最後のピースとして型パラメタを指定して完全確定する
2023/07/29(土) 19:01:27.37ID:mkN3FcGi
そうなんよねぇ
ML型型理論ならexpression毎に最も一般的な型が決まる
Haskellは型を指定しない場合自動的にその最も一般的な型を確定させてghciとかで調べられる
今のところ上がってる方法ではRustではそれに該当する方法はなさそう
2023/07/29(土) 19:02:57.30ID:mkN3FcGi
イヤまだvscideとかのやつは試してないな
これならできるんかな?
833デフォルトの名無しさん
垢版 |
2023/07/29(土) 20:36:12.76ID:JeVM9tS2
こいつダメだわ
ある意味複オジ2世
2023/07/29(土) 21:40:33.16ID:EPaDIYai
>>829
> Rustは最終的にコンパイルが終わって型が完全に推論が終わって単相型が決定した状態でしかわからないのかな
いやもうrustは変数宣言時に定義した型の変更を許さないのよ(基本的に)
だから型推論は変数宣言時のものを利用したり、関数の場合は返値、手打ちの数字の場合はデフォルトの型に決め打ちされて型推論されるわけ
いちいち型を調べる必要がない
ジェネリックに関しても基本的に場合分け
2023/07/29(土) 21:44:15.48ID:EPaDIYai
pythonとかjavascriptとか勝手に型を変更する(ような振る舞いをする→変更するとは言ってない)
言語なんてサイテーだと個人的には思う
2023/07/29(土) 22:05:07.65ID:2dUASh9D
>>834
どゆこと?
rustの型システムはしゃないの?
2023/07/29(土) 22:10:13.37ID:2dUASh9D
ごめん、誤字った
rustの型システムはMLじゃないの?
いわゆる型の全体と命題論理の全体を一対一に対応させる
で、その命題論理の目モデルを探す事=単相型を決定する事がMLの型推論システムで、Rustもそれ採用してるんだと思ってるんだけど
で単相型が割り当てられる“命題”に対応してるものが多相型と呼ぶんだと教えてもらった事あるけど
2023/07/29(土) 22:19:51.45ID:381IW7f/
も少し書くなら基本的にrustもhaskellも型システムは基本的な原理は同じじゃないのって話
それを説明する用語としてRust特定の説明の仕方をしてるのかもしれないけど説明の仕方や用語の使い方を変えたところでどっちもカリーハワード理論に基づく型システムじゃない?
2023/07/29(土) 22:51:50.32ID:381IW7f/
もし同じならHaskellと同じく例えば

mysum [] = 0
mysum (a:as) = a + ( mysum as )

なら Haskell ならmysumの型は

( Num a ) => [ a ] -> a

と推論されます
RustでもML型システムである限り少なくとも内部的には同じような型が割り当てられてるはずだと思うんですけど
もちろんこれら推論された型を全部総合して実装時には特定の単相型が割り当てられます
この辺のメカニズムはHaskellもRustも同じじゃないんでしょうか?
2023/07/29(土) 23:06:20.41ID:MBm8IaU2
まずRustの数値リテラルはHaskellと違って多相な型を持たないです
2023/07/29(土) 23:25:14.79ID:I6XWshKt
>>839
分かってる気になっておかしなことを書く癖を直したほうがいいと思うが…
2023/07/29(土) 23:36:28.14ID:I6XWshKt
人間としての推論機構が間違っている

基礎を勉強してルールとしてそれを覚えてから
それを基に推論を行わないと意味がないと知るべき
2023/07/29(土) 23:51:52.56ID:nTghkNr5
>>831
最も一般的な型ではダメでRustは唯一に確定しなければならない
Rustは関数(メソッド)の引数も返り値も型宣言が必須だけど
そこでの型はジェネリックで型パラメータを持つものも多く
その型パラメータのトレイト境界などによる制約とそのトレイト実装をする型が複数あることから複数解も生じる
複数解がありうるならばコンパイルエラーとなり明示的な型指定を求められる
唯一の例外が数値リテラルの利用により数値型までは確定している時でそれが整数ならば自動的にi32型に解決される
2023/07/30(日) 00:16:28.33ID:psEFm3Dt
>>840
その説明はよくrustの解説本にあるけど多分字面通りの意味にとってはいけないんじゃないかと
だってプログラム全体を見なければ型なんか決められるはずない
ML型の型システムである限りHaskellのexpressionから定まる最も一般的な多相型持ってると思う、でなければML型型システムと呼べない
さっきあげたmysumなんかその典型、あのmusumはnum classに属するすべての型で使うことができる、もしこのような多相型を持たない理論ならすべての足し算を持つクラス全てにほとんど同じsumを定義させられることになる、それを避けられるのがML型システムの1番の売りなんだから
てか上の例のmysumに相当する書き方Rustでもできるんでしょ?
無理なん?
2023/07/30(日) 00:18:56.60ID:psEFm3Dt
ML型システムと呼べないは言い過ぎかな?
まぁ型宣言省略しても型推論してくれるならML型型システムと呼べなくはないけど、でも流石にさっきのmysumみたいな記述は許されてるんじゃないの?
2023/07/30(日) 00:19:43.44ID:dT6HJfPv
ハスケル!
ハスケル!
ハスケル!

その毎度のハスケルおじさんに構うのは止めとけよ
Rubyおじさんと変わらないんだからさあ
自覚のない荒らしだよ
2023/07/30(日) 00:19:47.09ID:psEFm3Dt
>>843
そうなん?
じゃあさっきのmysumみたいな書き方はRustではできないのあ?
2023/07/30(日) 00:21:02.70ID:dT6HJfPv
Haskellおじさんは自分の思いをここに書かないと死んじゃうの?
なんでRustをRustとして扱いたくないの?
2023/07/30(日) 00:21:05.69ID:psEFm3Dt
>>846
目障りなら無視してくれていいけど純粋に新しいプログラミング言語に挑戦してるだけだから邪魔しないでくれる?
君は一生ひRustに捧げればいいやん
2023/07/30(日) 00:22:04.96ID:dT6HJfPv
ハスケルおじさんは壁に向かってハスケルハスケル行ってればいいのに
2023/07/30(日) 00:24:01.50ID:dT6HJfPv
マクロしらんの?
2023/07/30(日) 00:24:09.72ID:psEFm3Dt
>>848
すでに習得した言語の対比して新しい言語に挑戦するのは当たり前やろ?
Haskellの型システム理解するのにどれだけの時間をかけて教科書を読み、論文を読み、プログラミングを組んでみたか、その資産を使いたいとおもうのがそんなに悪いんか?
黙っといてくれよ
2023/07/30(日) 00:24:40.66ID:dT6HJfPv
>>852
悪いに決まってるだろ?
そんなこともわからんの?
2023/07/30(日) 00:26:23.01ID:dT6HJfPv
論文読まないとプログラム言語が理解できないんだから困ったやつだろ
推論システムが変
2023/07/30(日) 00:29:41.31ID:dT6HJfPv
まずは"真面目にRust学習"しろ
そして習得しろ
そして疑問を解決しろ
2023/07/30(日) 00:32:06.97ID:psEFm3Dt
>>854
すまんけどオレは論文なんか読まなくても理解できるような天才じゃないんだよ
君は論文なんぞ読まなくても何もかもわかる天才なのかもしれんけど世の中そんな天才ばかりじゃないんだよ
オレみたいに寝食忘れて努力に努力を重ねてやっと話しが分かる鈍才もいるんだよ
鈍才が悪あがきするの邪魔せんでくれ
2023/07/30(日) 00:33:26.30ID:psEFm3Dt
>>855
もうオレに関わらないで
その方が双方幸せじゃないか?
858デフォルトの名無しさん
垢版 |
2023/07/30(日) 02:16:35.97ID:ArPWIRVu
大先生3人に共通するのは
自分は分かってるという根拠のない思い込みと
何度指摘されても全く反省せず同じことを繰り返す傍迷惑な行動
2023/07/30(日) 02:39:34.14ID:g1ghpAt+
>>847
consセルを使った簡易なリスト操作表記をRustは言語仕様レベルではサポートしていない
だからそのHaskellのmysumをその表現のまま移植するのは本質的ではないため
意味だけを重視してリストをイテレータで表現し再帰定義している点を尊重すると

use std::ops::Add;
use num::Zero;

fn mysum<T>(mut iter: impl Iterator<Item = T>) -> T
where
T: Zero + Add<Output = T>,
{
match iter.next() {
Some(n) => n + mysum(iter),
None => T::zero(),
}
}

一例としてこのようにmysumはジェネリックに書ける
mysumに最低限必要なトレイト境界(Zero + Add)のみを課している
もちろんこの関数だけで以下のように機能して計算結果も合う
assert_eq!(15, mysum([1, 2, 3, 4, 5].into_iter()));
2023/07/30(日) 02:43:03.72ID:g1ghpAt+
>>859のmysumでトレイト境界はZeroとAddさえ満たしていれば通常の数値でなくても構わないので
例えば以下のようなHoge型を定義して必要なトレイト境界(ZeroとAdd)を実装すると

#[derive(PartialEq, Debug)]
struct Hoge(usize);
impl Zero for Hoge {
fn zero() -> Self { Hoge(0) }
fn is_zero(&self) -> bool { self.0 == 0 }
}
impl Add for Hoge {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Hoge((1 << (self.0.trailing_ones() + rhs.0.trailing_ones())) - 1)
}
}

先程と同じように「15 = 1 + 2 + 3 + 4 + 5」をHoge型で表現することで
Hogeについてもmysum()は以下のようにきちんと計算できていることがわかる
assert_eq!(Hoge(0b111111111111111), mysum([Hoge(0b1), Hoge(0b11), Hoge(0b111), Hoge(0b1111), Hoge(0b11111)].into_iter()));

Haskellに全く詳しくないので逆に質問というか教えてほしい
このHoge型をHaskellで定義(実装)するにはどのようなコードになるのか?
そしてこのHoge型に対してもHaskell版>>839のmysumで使えるようにするにはどうするのか?
たぶん型クラスNumの代わりに型クラスZeroとAddを指定するだけで済むのだろうけど
もしHaskellに型クラスZeroやAddがなければそれを定義する形になるのだろうか?
よろしくお願いします
2023/07/30(日) 10:57:59.43ID:TSIasAnA
>>860
Haskellではこうなります
https://ideone.com/PKy694

mysum [] = 0
mysum ( a : as ) = a + ( mysum as )

hogePlus a 0 = a
hogePlus a b | even b = 2 * (hogePlus a ( div b 2 ) )
hogePlus a b = 1 + 2 * (hogePlus a ( div b 2 ) )

data Hoge = H Integer deriving Show

instance Num Hoge where
( H x ) + ( H y ) = H ( hogePlus x y )
fromInteger = H

main = do
print $ mysum [ 1..5 ]
print $ hogePlus 3 7
print $ mysum [ H 1, H 3, H 7, H 15, H 31 ]
2023/07/30(日) 10:58:19.77ID:TSIasAnA
この例だとmysumの型は
mysum :: ( Num a ) => [ a ] -> a
と推論されます
すなわちmysumは

 aがNum class に属する型aに対して[a]型の値に対してa型の値を返す関数の型

です
よってmysumをある型Hogeで利用するにはHogeにNumインスタンスを導入しなければなりません、すなわちRustでは
impl Num for Hoge { ... }
のように書く部分です( >> 860 のAdd,Zeroを実装してる部分に該当します)
本来はNumのminimal complete definition全部実装するべきでHaskell1990までは“定義が揃ってない”とおこられましたが。2010以降は必要な分だけ実装すれば良い、ただし実行時エラーは覚悟しろという風に変更されてるようです(未確認、コンパイラがエラー吐かなくなったので)
2023/07/30(日) 12:33:59.93ID:g1ghpAt+
>>861
RustのAddトレイト実装によって足し算(a + b)のみを他の型でも自由に使えるようにできる機能をHaskellは持っていないということ?
そのためHaskellではやむを得ない代替処置としてHoge型を型クラスNumへ入れてしまうことで解決したということ?

例えばRustではStringについてもAddトレイト実装があり
let s = String::from("abc");
assert_eq!(s + "xyz", String::from("abcxyz"));
といったこともできます
同様に自作の型に対しても足し算のみの実装が可能です
Haskellではこのようなケースでもオーバースペック気味にNumを使うしかないのでしょうか?
2023/07/30(日) 12:37:15.22ID:g1ghpAt+
>>862
Haskellでは実行時エラーを覚悟しろという点は非常に困りますね
今回のケースも無理やりにNumへ入れてしまったのに足し算しか実装していないから引き算や掛け算などで実行時エラーとなるわけですよね

ちなみにRustのnumクレートでは
trait Num: Zero + One + NumOps + PartialEq とトレイト境界があり
impl NumOps for T where T: Add + Sub + Mul + Div + Rem {} の実装があります
つまり自作の型で使う場合は全ての演算を実装した上で更に加えて
impl Num for Foo とするとようやくNumになれます
したがってRustでは不備があればコンパイル時エラーとなり安心して安全に使うことができます
2023/07/30(日) 12:47:58.55ID:wjjxPYUe
そろそろ隔離スレ行ってろカスども
2023/07/30(日) 14:02:34.57ID:iwDEPHME
Haskell 的には演算子オーバーロードを目的として型クラスを使うことはしない。
Num な性質を持つ値の操作として + という名前の演算子もあるというだけで、
演算子として + を使いたいから型クラスの実装を定義するということはしないってこと。
それに、 Num はいくつかの演算子を使えるというだけではなく
それらの演算子の関係で満たさなければいけない性質があるので個々の演算子 (に結び付く型クラス) として分解できない。
https://hackage.haskell.org/package/base-4.18.0.0/docs/Prelude.html#t:Num

価値観が違う。

なんせ Haskell では記号を組み合わせていくらでも演算子を作ることが出来て
たとえば <$> とか >>= とかいう変な演算子を必要なだけ作れるので少ない演算子を取り合う必要がない。

Num の性質の中で + を使うってのと、
なんらかの足し算っぽい操作は別の名前で定義されているべきだし、
Haskell ではそれで困らない。

価値観が違う。
2023/07/30(日) 18:06:30.12ID:mgfeU+D6
新設の見慣れぬ演算子の種類を勝手に増やして各々が異なる意味付けすることは可読性を下げるのみで百害あって一利無し

>>862
コンパイラがエラーを吐かずに実行時エラーとなるのはマズいな
Haskellの価値観はよくない
2023/07/30(日) 19:58:32.75ID:Llc746TG
すいません、筆が滑りました
もちろんコンパイル時にエラー吐きます
以前のHaskellだと例えそのプログラムで使われてない場合でも実装しないとエラー吐いてました
しょうがないのでwhere句に使いもしないのに
_ * _ = undefined
signum _ = undefined
....
を書いてました
流石に無意味すぎて使わないのは書かなくて良いことになったようです
使ってるのに未実装はもちろんコンパイラが見つけてくれます
2023/07/30(日) 20:06:02.24ID:iwDEPHME
どうでもいいけど signum という名前を見るとヴォルケンリッターを連想してしまう……
2023/07/31(月) 08:16:09.72ID:G+nEO2Oo
どうでもいいなら・・・煽りたくなるな
2023/07/31(月) 10:23:47.98ID:8wbRk2dY
use Hoge::prelude::*; って良く観るがダサいなー
2023/07/31(月) 10:35:07.69ID:i3Lje9zm
でもまあ機能ごとにモジュールを整理しても
それとは別によく使う集合があるのも現実だし。
2023/07/31(月) 11:07:00.50ID:sgBBFIN2
global 禁止(キリっ
2023/07/31(月) 12:25:28.59ID:lZja90Kc
>>871
preludeは邪道で非推奨
自動適用される標準ライブラリのprelude以外は使わない&設けない
例えばtokio::preludeも廃止された
2023/07/31(月) 12:34:21.81ID:eCR2qI4e
Rustで、Vecに要素を追加したとき、メモリ不足で
メモリ確保に失敗した場合、どうなるんですか?
C++の場合は「例外」がthrowされますが。
2023/07/31(月) 14:38:56.18ID:uDpaCeqo
pqnic
2023/07/31(月) 16:40:54.67ID:cE0Z6rmj
ピクニック?
2023/07/31(月) 17:53:43.20ID:1dCFbVL1
fn っていちいち略さなくても function でよくない?

書き込める変数の宣言に mut ってつけるのもダサい
2023/07/31(月) 18:05:43.81ID:+bjI2PCn
mutはガチでダサい
何かいい記号はなかったのかとw
2023/07/31(月) 18:13:53.64ID:+bjI2PCn
英語圏の人たちはmut見てcoolに感じるとか日本人と感性が違う可能性がある
2023/07/31(月) 18:38:57.32ID:9nT3Yxeb
>>878
感性が古いよ
2023/07/31(月) 18:48:05.02ID:STr6yd2M
今までミュートと読んでいた
2023/07/31(月) 18:49:54.52ID:A3cMstwB
unicode解禁にして変にすればいい
884デフォルトの名無しさん
垢版 |
2023/07/31(月) 20:49:15.69ID:X0OEUfKN
>>881
短い略語を使いたがるのはメモリ容量が少なかった昔の習性・感性だろ。
昔に作られた言語のFortranとPascalですらfunctionは略さなかったのに、
今になって変な略語を採用したRust開発者は工学的センスも美的センスもない。

比較的新しい言語のF#はmutと略さずにmutableと書く。
2023/07/31(月) 21:15:27.96ID:+bjI2PCn
BASICの頃はDEF FNと言うので関数を定義してた
2023/07/31(月) 21:25:40.03ID:4/4p/Sxt
様々なプログラミング言語があって千差万別な中
大した問題ではないキーワード名やその多少の長さに文句をつける人はダメな仕事できないやつ
仕事できる人は文法とその意味論を比べる
2023/07/31(月) 21:34:38.41ID:+bjI2PCn
ダサいのはダサい

今後何があってもbegin end区切りの言語は使わないと思う
delphiやってた時もimplementationと言うのを見てクソダサいなと感じた
Objective-Cも二度と接することはないだろう
2023/07/31(月) 22:59:44.59ID:i3Lje9zm
kotlin や swift の前で同じこと言えるの?
2023/07/31(月) 23:19:46.93ID:+bjI2PCn
implementation Point {
public function ...
890デフォルトの名無しさん
垢版 |
2023/08/01(火) 03:00:40.65ID:8wU+ches
>>880
constより2文字も短い!かっけええぇぇぇ!!!
かもな
同意しないけど
2023/08/01(火) 03:53:49.10ID:enF/Vqu1
constは定数だからコンパイル時に静的に確定する
immutableかmutableかというのはconstとは無関係な概念で実行時の変数の値が書き換わるかどうか
つまりRustの非mut (immutable)は定数ではなく実行時に値が決まる変数
2023/08/01(火) 11:16:59.87ID:AvEKEx5a
let x : u32 = 1234;

const x : u32 = 1234;
は違うんですか?
2023/08/01(火) 11:22:28.49ID:AvEKEx5a
なるほど、const = の右辺値はconst 文脈で書かれていてコンパイル時に決定できないといけないけど let = の右辺はその制約がないのか
2023/08/01(火) 17:52:49.94ID:3uGNwlqu
constはコンパイル時に値が決まる定数となり定数名は大文字で書く
letは(mutの有無に関係なく)実行時に値が決まる変数となり変数名は小文字で書く
mutの有無はその変数の値が書き換えられるかどうかだけの違い
2023/08/01(火) 18:49:11.32ID:Nt/KTAzO
自分は素人だけどそれじゃあ型に対する言及が抜けてないですか?
2023/08/01(火) 20:27:35.06ID:3uGNwlqu
型とは直交する概念なので型とは無関係
任意の型で成り立つ
2023/08/01(火) 22:08:28.57ID:YdsBZTXH
'static
2023/08/01(火) 22:38:58.55ID:Nt/KTAzO
constはシャドーイングは行われない
変数と違い型を必ず明示しなくてはならない
2023/08/02(水) 00:09:43.49ID:IOFZl0B3
>>898
なんでですか?
constシャドーイングしてなんか不都合あります?
900デフォルトの名無しさん
垢版 |
2023/08/02(水) 00:12:43.58ID:/ED8qpF1
>>892
constならROM領域に置ける
2023/08/02(水) 00:12:59.71ID:IOFZl0B3
あ、わかった
そりゃそうだ
902デフォルトの名無しさん
垢版 |
2023/08/02(水) 09:00:43.40ID:4pI1Wfnv
関数名というか関数を格納した変数?にもmut付けるときあるけど
動作中に関数を変えるのが目的?って表明以外の意味ある?
2023/08/02(水) 13:19:46.95ID:MBDISWVo
関数ポインタかラムダ式(クロージャ)かで意味が変わりそうだな

関数ポインタの場合は途中で別の同型の関数に差し替えるときにmutが必要
クロージャの場合は途中で内部の変数が変更される(FnMutになる)ときにmutが必要
(クロージャは型の関係で別の関数に差し替えることはできないはず)

下の例だとf,gのどちらもmutがないと怒られる

fn print_foo() { println!("foo"); }
fn print_bar() { println!("bar"); }

fn main() {
let mut f: fn();
f = print_foo;
f();
f = print_bar;
f();

let mut i = 0u32;
let mut g = move || { println!("{i}"); i += 1; };

for _ in 0..5 { g(); }
}
2023/08/02(水) 13:23:57.98ID:MBDISWVo
そこに置かれてる値(関数ポインタ or クロージャ)が変更されるという意味では同じか
2023/08/02(水) 18:24:39.32ID:SI51iZ7R
let mut hoge; じゃなくて

むしろ let hoge = 3; と mut hoge = 3; の二種類に分ければ美しくてよ
2023/08/02(水) 19:02:02.79ID:F3jAz55G
static mut もあるし
letはパターンマッチ文だからlet (mut a, b) もあるし
if let Some((ref mut p, ref q)) もあるし
レス数が900を超えています。1000を超えると表示できなくなるよ。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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