公式
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/
Rust part20
レス数が950を超えています。1000を超えると書き込みができなくなります。
2023/03/03(金) 00:45:28.73ID:vTVY069B
851デフォルトの名無しさん
2023/07/30(日) 00:24:01.50ID:dT6HJfPv マクロしらんの?
852デフォルトの名無しさん
2023/07/30(日) 00:24:09.72ID:psEFm3Dt >>848
すでに習得した言語の対比して新しい言語に挑戦するのは当たり前やろ?
Haskellの型システム理解するのにどれだけの時間をかけて教科書を読み、論文を読み、プログラミングを組んでみたか、その資産を使いたいとおもうのがそんなに悪いんか?
黙っといてくれよ
すでに習得した言語の対比して新しい言語に挑戦するのは当たり前やろ?
Haskellの型システム理解するのにどれだけの時間をかけて教科書を読み、論文を読み、プログラミングを組んでみたか、その資産を使いたいとおもうのがそんなに悪いんか?
黙っといてくれよ
853デフォルトの名無しさん
2023/07/30(日) 00:24:40.66ID:dT6HJfPv854デフォルトの名無しさん
2023/07/30(日) 00:26:23.01ID:dT6HJfPv 論文読まないとプログラム言語が理解できないんだから困ったやつだろ
推論システムが変
推論システムが変
855デフォルトの名無しさん
2023/07/30(日) 00:29:41.31ID:dT6HJfPv まずは"真面目にRust学習"しろ
そして習得しろ
そして疑問を解決しろ
そして習得しろ
そして疑問を解決しろ
856デフォルトの名無しさん
2023/07/30(日) 00:32:06.97ID:psEFm3Dt >>854
すまんけどオレは論文なんか読まなくても理解できるような天才じゃないんだよ
君は論文なんぞ読まなくても何もかもわかる天才なのかもしれんけど世の中そんな天才ばかりじゃないんだよ
オレみたいに寝食忘れて努力に努力を重ねてやっと話しが分かる鈍才もいるんだよ
鈍才が悪あがきするの邪魔せんでくれ
すまんけどオレは論文なんか読まなくても理解できるような天才じゃないんだよ
君は論文なんぞ読まなくても何もかもわかる天才なのかもしれんけど世の中そんな天才ばかりじゃないんだよ
オレみたいに寝食忘れて努力に努力を重ねてやっと話しが分かる鈍才もいるんだよ
鈍才が悪あがきするの邪魔せんでくれ
857デフォルトの名無しさん
2023/07/30(日) 00:33:26.30ID:psEFm3Dt858デフォルトの名無しさん
2023/07/30(日) 02:16:35.97ID:ArPWIRVu 大先生3人に共通するのは
自分は分かってるという根拠のない思い込みと
何度指摘されても全く反省せず同じことを繰り返す傍迷惑な行動
自分は分かってるという根拠のない思い込みと
何度指摘されても全く反省せず同じことを繰り返す傍迷惑な行動
859デフォルトの名無しさん
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()));
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()));
860デフォルトの名無しさん
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がなければそれを定義する形になるのだろうか?
よろしくお願いします
例えば以下のような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がなければそれを定義する形になるのだろうか?
よろしくお願いします
861デフォルトの名無しさん
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 ]
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 ]
862デフォルトの名無しさん
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以降は必要な分だけ実装すれば良い、ただし実行時エラーは覚悟しろという風に変更されてるようです(未確認、コンパイラがエラー吐かなくなったので)
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以降は必要な分だけ実装すれば良い、ただし実行時エラーは覚悟しろという風に変更されてるようです(未確認、コンパイラがエラー吐かなくなったので)
863デフォルトの名無しさん
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を使うしかないのでしょうか?
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を使うしかないのでしょうか?
864デフォルトの名無しさん
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では不備があればコンパイル時エラーとなり安心して安全に使うことができます
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では不備があればコンパイル時エラーとなり安心して安全に使うことができます
865デフォルトの名無しさん
2023/07/30(日) 12:47:58.55ID:wjjxPYUe そろそろ隔離スレ行ってろカスども
866デフォルトの名無しさん
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 ではそれで困らない。
価値観が違う。
Num な性質を持つ値の操作として + という名前の演算子もあるというだけで、
演算子として + を使いたいから型クラスの実装を定義するということはしないってこと。
それに、 Num はいくつかの演算子を使えるというだけではなく
それらの演算子の関係で満たさなければいけない性質があるので個々の演算子 (に結び付く型クラス) として分解できない。
https://hackage.haskell.org/package/base-4.18.0.0/docs/Prelude.html#t:Num
価値観が違う。
なんせ Haskell では記号を組み合わせていくらでも演算子を作ることが出来て
たとえば <$> とか >>= とかいう変な演算子を必要なだけ作れるので少ない演算子を取り合う必要がない。
Num の性質の中で + を使うってのと、
なんらかの足し算っぽい操作は別の名前で定義されているべきだし、
Haskell ではそれで困らない。
価値観が違う。
867デフォルトの名無しさん
2023/07/30(日) 18:06:30.12ID:mgfeU+D6 新設の見慣れぬ演算子の種類を勝手に増やして各々が異なる意味付けすることは可読性を下げるのみで百害あって一利無し
>>862
コンパイラがエラーを吐かずに実行時エラーとなるのはマズいな
Haskellの価値観はよくない
>>862
コンパイラがエラーを吐かずに実行時エラーとなるのはマズいな
Haskellの価値観はよくない
868デフォルトの名無しさん
2023/07/30(日) 19:58:32.75ID:Llc746TG すいません、筆が滑りました
もちろんコンパイル時にエラー吐きます
以前のHaskellだと例えそのプログラムで使われてない場合でも実装しないとエラー吐いてました
しょうがないのでwhere句に使いもしないのに
_ * _ = undefined
signum _ = undefined
....
を書いてました
流石に無意味すぎて使わないのは書かなくて良いことになったようです
使ってるのに未実装はもちろんコンパイラが見つけてくれます
もちろんコンパイル時にエラー吐きます
以前のHaskellだと例えそのプログラムで使われてない場合でも実装しないとエラー吐いてました
しょうがないのでwhere句に使いもしないのに
_ * _ = undefined
signum _ = undefined
....
を書いてました
流石に無意味すぎて使わないのは書かなくて良いことになったようです
使ってるのに未実装はもちろんコンパイラが見つけてくれます
869デフォルトの名無しさん
2023/07/30(日) 20:06:02.24ID:iwDEPHME どうでもいいけど signum という名前を見るとヴォルケンリッターを連想してしまう……
870デフォルトの名無しさん
2023/07/31(月) 08:16:09.72ID:G+nEO2Oo どうでもいいなら・・・煽りたくなるな
871デフォルトの名無しさん
2023/07/31(月) 10:23:47.98ID:8wbRk2dY use Hoge::prelude::*; って良く観るがダサいなー
872デフォルトの名無しさん
2023/07/31(月) 10:35:07.69ID:i3Lje9zm でもまあ機能ごとにモジュールを整理しても
それとは別によく使う集合があるのも現実だし。
それとは別によく使う集合があるのも現実だし。
873デフォルトの名無しさん
2023/07/31(月) 11:07:00.50ID:sgBBFIN2 global 禁止(キリっ
874デフォルトの名無しさん
2023/07/31(月) 12:25:28.59ID:lZja90Kc875デフォルトの名無しさん
2023/07/31(月) 12:34:21.81ID:eCR2qI4e Rustで、Vecに要素を追加したとき、メモリ不足で
メモリ確保に失敗した場合、どうなるんですか?
C++の場合は「例外」がthrowされますが。
メモリ確保に失敗した場合、どうなるんですか?
C++の場合は「例外」がthrowされますが。
876デフォルトの名無しさん
2023/07/31(月) 14:38:56.18ID:uDpaCeqo pqnic
877デフォルトの名無しさん
2023/07/31(月) 16:40:54.67ID:cE0Z6rmj ピクニック?
878デフォルトの名無しさん
2023/07/31(月) 17:53:43.20ID:1dCFbVL1 fn っていちいち略さなくても function でよくない?
書き込める変数の宣言に mut ってつけるのもダサい
書き込める変数の宣言に mut ってつけるのもダサい
879デフォルトの名無しさん
2023/07/31(月) 18:05:43.81ID:+bjI2PCn mutはガチでダサい
何かいい記号はなかったのかとw
何かいい記号はなかったのかとw
880デフォルトの名無しさん
2023/07/31(月) 18:13:53.64ID:+bjI2PCn 英語圏の人たちはmut見てcoolに感じるとか日本人と感性が違う可能性がある
881デフォルトの名無しさん
2023/07/31(月) 18:38:57.32ID:9nT3Yxeb >>878
感性が古いよ
感性が古いよ
882デフォルトの名無しさん
2023/07/31(月) 18:48:05.02ID:STr6yd2M 今までミュートと読んでいた
883デフォルトの名無しさん
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と書く。
短い略語を使いたがるのはメモリ容量が少なかった昔の習性・感性だろ。
昔に作られた言語のFortranとPascalですらfunctionは略さなかったのに、
今になって変な略語を採用したRust開発者は工学的センスも美的センスもない。
比較的新しい言語のF#はmutと略さずにmutableと書く。
885デフォルトの名無しさん
2023/07/31(月) 21:15:27.96ID:+bjI2PCn BASICの頃はDEF FNと言うので関数を定義してた
886デフォルトの名無しさん
2023/07/31(月) 21:25:40.03ID:4/4p/Sxt 様々なプログラミング言語があって千差万別な中
大した問題ではないキーワード名やその多少の長さに文句をつける人はダメな仕事できないやつ
仕事できる人は文法とその意味論を比べる
大した問題ではないキーワード名やその多少の長さに文句をつける人はダメな仕事できないやつ
仕事できる人は文法とその意味論を比べる
887デフォルトの名無しさん
2023/07/31(月) 21:34:38.41ID:+bjI2PCn ダサいのはダサい
今後何があってもbegin end区切りの言語は使わないと思う
delphiやってた時もimplementationと言うのを見てクソダサいなと感じた
Objective-Cも二度と接することはないだろう
今後何があってもbegin end区切りの言語は使わないと思う
delphiやってた時もimplementationと言うのを見てクソダサいなと感じた
Objective-Cも二度と接することはないだろう
888デフォルトの名無しさん
2023/07/31(月) 22:59:44.59ID:i3Lje9zm kotlin や swift の前で同じこと言えるの?
889デフォルトの名無しさん
2023/07/31(月) 23:19:46.93ID:+bjI2PCn implementation Point {
public function ...
}
public function ...
}
890デフォルトの名無しさん
2023/08/01(火) 03:00:40.65ID:8wU+ches891デフォルトの名無しさん
2023/08/01(火) 03:53:49.10ID:enF/Vqu1 constは定数だからコンパイル時に静的に確定する
immutableかmutableかというのはconstとは無関係な概念で実行時の変数の値が書き換わるかどうか
つまりRustの非mut (immutable)は定数ではなく実行時に値が決まる変数
immutableかmutableかというのはconstとは無関係な概念で実行時の変数の値が書き換わるかどうか
つまりRustの非mut (immutable)は定数ではなく実行時に値が決まる変数
892デフォルトの名無しさん
2023/08/01(火) 11:16:59.87ID:AvEKEx5a let x : u32 = 1234;
と
const x : u32 = 1234;
は違うんですか?
と
const x : u32 = 1234;
は違うんですか?
893デフォルトの名無しさん
2023/08/01(火) 11:22:28.49ID:AvEKEx5a なるほど、const = の右辺値はconst 文脈で書かれていてコンパイル時に決定できないといけないけど let = の右辺はその制約がないのか
894デフォルトの名無しさん
2023/08/01(火) 17:52:49.94ID:3uGNwlqu constはコンパイル時に値が決まる定数となり定数名は大文字で書く
letは(mutの有無に関係なく)実行時に値が決まる変数となり変数名は小文字で書く
mutの有無はその変数の値が書き換えられるかどうかだけの違い
letは(mutの有無に関係なく)実行時に値が決まる変数となり変数名は小文字で書く
mutの有無はその変数の値が書き換えられるかどうかだけの違い
895デフォルトの名無しさん
2023/08/01(火) 18:49:11.32ID:Nt/KTAzO 自分は素人だけどそれじゃあ型に対する言及が抜けてないですか?
896デフォルトの名無しさん
2023/08/01(火) 20:27:35.06ID:3uGNwlqu 型とは直交する概念なので型とは無関係
任意の型で成り立つ
任意の型で成り立つ
897デフォルトの名無しさん
2023/08/01(火) 22:08:28.57ID:YdsBZTXH 'static
898デフォルトの名無しさん
2023/08/01(火) 22:38:58.55ID:Nt/KTAzO constはシャドーイングは行われない
変数と違い型を必ず明示しなくてはならない
変数と違い型を必ず明示しなくてはならない
899デフォルトの名無しさん
2023/08/02(水) 00:09:43.49ID:IOFZl0B3900デフォルトの名無しさん
2023/08/02(水) 00:12:43.58ID:/ED8qpF1 >>892
constならROM領域に置ける
constならROM領域に置ける
901デフォルトの名無しさん
2023/08/02(水) 00:12:59.71ID:IOFZl0B3 あ、わかった
そりゃそうだ
そりゃそうだ
902デフォルトの名無しさん
2023/08/02(水) 09:00:43.40ID:4pI1Wfnv 関数名というか関数を格納した変数?にもmut付けるときあるけど
動作中に関数を変えるのが目的?って表明以外の意味ある?
動作中に関数を変えるのが目的?って表明以外の意味ある?
903デフォルトの名無しさん
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(); }
}
関数ポインタの場合は途中で別の同型の関数に差し替えるときに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(); }
}
904デフォルトの名無しさん
2023/08/02(水) 13:23:57.98ID:MBDISWVo そこに置かれてる値(関数ポインタ or クロージャ)が変更されるという意味では同じか
905デフォルトの名無しさん
2023/08/02(水) 18:24:39.32ID:SI51iZ7R let mut hoge; じゃなくて
むしろ let hoge = 3; と mut hoge = 3; の二種類に分ければ美しくてよ
むしろ let hoge = 3; と mut hoge = 3; の二種類に分ければ美しくてよ
906デフォルトの名無しさん
2023/08/02(水) 19:02:02.79ID:F3jAz55G static mut もあるし
letはパターンマッチ文だからlet (mut a, b) もあるし
if let Some((ref mut p, ref q)) もあるし
letはパターンマッチ文だからlet (mut a, b) もあるし
if let Some((ref mut p, ref q)) もあるし
907デフォルトの名無しさん
2023/08/02(水) 20:18:56.34ID:/ED8qpF1 >>905
それは無い
それは無い
908デフォルトの名無しさん
2023/08/03(木) 07:43:41.06ID:9tsUh6Bs 速い! 安全! ださい!
909デフォルトの名無しさん
2023/08/03(木) 08:17:38.34ID:8npqW66R >>906
mutを単独キーワードに分離したRustの設計方針の勝利だな
mutを単独キーワードに分離したRustの設計方針の勝利だな
910デフォルトの名無しさん
2023/08/03(木) 10:00:57.61ID:W+hOnHrE かわいい
北朝鮮みたい
北朝鮮みたい
911デフォルトの名無しさん
2023/08/03(木) 21:15:21.47ID:j7849mpF こんなスレ見てるなんてダサいぞ!
912デフォルトの名無しさん
2023/08/04(金) 09:07:52.99ID:XLfSEGlw かわいい
埼玉県みたい
埼玉県みたい
913デフォルトの名無しさん
2023/08/06(日) 17:59:34.17ID:xBSreVT+ 任意長整数型演算の実装の演習してるんですけど
・和の時には下の桁から、大小の比較の時は上の桁から順次比較するので双方からのアクセスをO(1)で行いたい
・任意長なので加法のときにover flowしたときitemの追加ができないとダメ
この場合どのcollection型が有利ですか?
ソースが難しすぎてわかりません
情報お願いいたします
・和の時には下の桁から、大小の比較の時は上の桁から順次比較するので双方からのアクセスをO(1)で行いたい
・任意長なので加法のときにover flowしたときitemの追加ができないとダメ
この場合どのcollection型が有利ですか?
ソースが難しすぎてわかりません
情報お願いいたします
914デフォルトの名無しさん
2023/08/06(日) 19:27:39.64ID:3wcIZOky 自分ならVec使う
915デフォルトの名無しさん
2023/08/06(日) 19:29:40.12ID:lVXXe/mp >>913
何を問題にしているのかわからない
言語に関係なく連続体のデータ型(配列やベクタなど)の順次アクセスは
前から後ろから関係なくサイズNに対して総コストO(N)で1つあたりO(1)
それらのうち固定長ではなくサイズを伸ばせるデータ型(ベクタ)なら要素を追加できる
RustならVec
何を問題にしているのかわからない
言語に関係なく連続体のデータ型(配列やベクタなど)の順次アクセスは
前から後ろから関係なくサイズNに対して総コストO(N)で1つあたりO(1)
それらのうち固定長ではなくサイズを伸ばせるデータ型(ベクタ)なら要素を追加できる
RustならVec
916デフォルトの名無しさん
2023/08/06(日) 20:21:24.84ID:xBSreVT+917デフォルトの名無しさん
2023/08/06(日) 20:24:19.56ID:xBSreVT+ >>914
ありがとう
確かに片方だけ伸ばすならbecで良さそうなんですよね
しかし後でよくよく考えたら掛け算の時に一の位の方向にも伸ばせた方が便利な気もしてきて
でもそっちは絶対じゃないんですよね
なんせvecのソースがむずい
ありがとう
確かに片方だけ伸ばすならbecで良さそうなんですよね
しかし後でよくよく考えたら掛け算の時に一の位の方向にも伸ばせた方が便利な気もしてきて
でもそっちは絶対じゃないんですよね
なんせvecのソースがむずい
918デフォルトの名無しさん
2023/08/06(日) 20:32:19.03ID:Mgx3ApDu ソースよりドキュメントを見なよ。
図つきで解説されてるから。
Vec は必要に応じて自動で再配置する配列ってかんじ。
要素は連続して配置される。
図つきで解説されてるから。
Vec は必要に応じて自動で再配置する配列ってかんじ。
要素は連続して配置される。
919デフォルトの名無しさん
2023/08/06(日) 20:50:29.31ID:WEauDaB9 >>918
https://doc.rust-lang.org/std/collections/index.html
とか読んだんですけどよくわからないんですよ
rust専用スレならstd::vec全部目を通せてる人いるかなと
連続して確保される領域の幅とかは指定できます?
https://doc.rust-lang.org/std/collections/index.html
とか読んだんですけどよくわからないんですよ
rust専用スレならstd::vec全部目を通せてる人いるかなと
連続して確保される領域の幅とかは指定できます?
920デフォルトの名無しさん
2023/08/06(日) 20:51:36.50ID:lVXXe/mp >>916
性質が重要なのであってよほどのことがないかぎり実装内部のソースを知る必要はない
LinkedListは極一部の用途を除きほとんどの用途で遅く不利になり今回も考える必要はない
これらは言語と関係なく一般的な話
性質が重要なのであってよほどのことがないかぎり実装内部のソースを知る必要はない
LinkedListは極一部の用途を除きほとんどの用途で遅く不利になり今回も考える必要はない
これらは言語と関係なく一般的な話
921デフォルトの名無しさん
2023/08/06(日) 21:11:21.94ID:kGEgc8zj >>920
とりあえず今はガロアの連分数使って円周率の計算でもやってみようと思ってるんですけど、その場合計算する項のlog orderで桁数が増大していきます
でも例えばbinary splittingとかにすれば桁数の上昇具合が変わってきます
そういう用途に応じて適切なcollection型の使い分けできるようにしたいんですよ
あくまで練習なので
ソース読みはまぁ趣味みたいなもんなんですけどそもそもRustの自習が趣味なので
とりあえず今はガロアの連分数使って円周率の計算でもやってみようと思ってるんですけど、その場合計算する項のlog orderで桁数が増大していきます
でも例えばbinary splittingとかにすれば桁数の上昇具合が変わってきます
そういう用途に応じて適切なcollection型の使い分けできるようにしたいんですよ
あくまで練習なので
ソース読みはまぁ趣味みたいなもんなんですけどそもそもRustの自習が趣味なので
922デフォルトの名無しさん
2023/08/06(日) 21:11:35.12ID:Mgx3ApDu >>919
だからドキュメント読めってば。
Vec はポインタとキャパシティと長さを管理する仕組みだと書いてある。
https://doc.rust-lang.org/std/vec/struct.Vec.html#guarantees
実体が配列だからスライスの形で扱うことも出来る。
もし C++ を知ってるなら設計理念的には vectorと同じ感じとおもっていいと思う。
だからドキュメント読めってば。
Vec はポインタとキャパシティと長さを管理する仕組みだと書いてある。
https://doc.rust-lang.org/std/vec/struct.Vec.html#guarantees
実体が配列だからスライスの形で扱うことも出来る。
もし C++ を知ってるなら設計理念的には vectorと同じ感じとおもっていいと思う。
923デフォルトの名無しさん
2023/08/06(日) 21:16:41.06ID:kGEgc8zj >>922
まぁ実はちょっと立場上普通の人より深く知ってる事を要求されることが多いんですよ
もちろんRustを並の人より知ってると言えるには後何年か修行しないといけないんでしょうけど、そもそもRustについては趣味なのでそこまで深く理解しなくてもいいとは思ってます
まぁ趣味なのでボチボチ読みます
ありがとうございます
まぁ実はちょっと立場上普通の人より深く知ってる事を要求されることが多いんですよ
もちろんRustを並の人より知ってると言えるには後何年か修行しないといけないんでしょうけど、そもそもRustについては趣味なのでそこまで深く理解しなくてもいいとは思ってます
まぁ趣味なのでボチボチ読みます
ありがとうございます
924デフォルトの名無しさん
2023/08/06(日) 21:39:48.28ID:+jzrd7Vj Haskell君と同じ臭いがしますね〜w
925デフォルトの名無しさん
2023/08/06(日) 22:09:28.45ID:lVXXe/mp >>921
何度も書いて伝わっていると思うが各データ型の性質や各用途への向き不向きは使用言語と関係ない話
その適切なcollection型の使い分けというのが仮に必要だとしても各言語と関係なく抽象的なレベルで考えて可否を判断すべきこと
その上でベクタ型のデータ構造では何がいけないのかの問題点も見えてこない
何度も書いて伝わっていると思うが各データ型の性質や各用途への向き不向きは使用言語と関係ない話
その適切なcollection型の使い分けというのが仮に必要だとしても各言語と関係なく抽象的なレベルで考えて可否を判断すべきこと
その上でベクタ型のデータ構造では何がいけないのかの問題点も見えてこない
926デフォルトの名無しさん
2023/08/06(日) 22:29:25.87ID:jEjmg3Hf やっぱり>>913のようにサイズが不定である場合にはダメですね
The capacity of a vector is the amount of space allocated for any future elements that will be added onto the vector. This is not to be confused with the length of a vector, which specifies the number of actual elements within the vector. If a vector’s length exceeds its capacity, its capacity will automatically be increased, but its elements will have to be reallocated.
まぁ一般論ではなくて××桁まで計算するとか決めうちして使います
どのみち掛け算最終的にはFourier変換でやってみるつもりなのでその場合不定長だとメチャクチャ難しいし
The capacity of a vector is the amount of space allocated for any future elements that will be added onto the vector. This is not to be confused with the length of a vector, which specifies the number of actual elements within the vector. If a vector’s length exceeds its capacity, its capacity will automatically be increased, but its elements will have to be reallocated.
まぁ一般論ではなくて××桁まで計算するとか決めうちして使います
どのみち掛け算最終的にはFourier変換でやってみるつもりなのでその場合不定長だとメチャクチャ難しいし
927デフォルトの名無しさん
2023/08/06(日) 22:59:01.67ID:lVXXe/mp >>926
不定長なら再配置を含めてもVecが有利
再配置コストは例えば2^nから2^(n+1)へ広げる度にしか発生せず誤差となる
それよりも連続領域に配置されることによるメモリキャッシュ効果が絶対に効く
不定長なら再配置を含めてもVecが有利
再配置コストは例えば2^nから2^(n+1)へ広げる度にしか発生せず誤差となる
それよりも連続領域に配置されることによるメモリキャッシュ効果が絶対に効く
928デフォルトの名無しさん
2023/08/06(日) 23:14:54.40ID:vwDBawzd >>927
そうなんですか?
でもドキュメントには続いて
For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10 more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or cause reallocation to occur. However, if the vector’s length is increased to 11, it will have to reallocate, which can be slow. For this reason, it is recommended to use Vec::with_capacity whenever possible to specify how big the vector is expected to get.
とありますよ?
そうなんですか?
でもドキュメントには続いて
For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10 more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or cause reallocation to occur. However, if the vector’s length is increased to 11, it will have to reallocate, which can be slow. For this reason, it is recommended to use Vec::with_capacity whenever possible to specify how big the vector is expected to get.
とありますよ?
929デフォルトの名無しさん
2023/08/06(日) 23:50:23.90ID:lVXXe/mp それを読んで再配置があった場合でも1回あたりO(1)で済んでいることが理解できないならば
Rustの勉強でもなくプログラミングの勉強でもなくCSなどの基礎から学ぶことをおすすめする
そういう基礎を理解しないままO(1)で行ないたいと最初の質問で書いていたのもヤバい
何度も伝えているが各言語と関係なく成り立つ話なのだから各言語に立ち入る前に理解を済ませておくべき
Rustの勉強でもなくプログラミングの勉強でもなくCSなどの基礎から学ぶことをおすすめする
そういう基礎を理解しないままO(1)で行ないたいと最初の質問で書いていたのもヤバい
何度も伝えているが各言語と関係なく成り立つ話なのだから各言語に立ち入る前に理解を済ませておくべき
930デフォルトの名無しさん
2023/08/07(月) 00:14:34.21ID:KoOATDug931デフォルトの名無しさん
2023/08/07(月) 00:41:08.66ID:Sa+WohTx “amortized O(N)”を”1回あたりO(1)”に変換するあたりは流石オジ
でもCS基礎を学べというオジの主張に今回ばかりは同意するよ
でもCS基礎を学べというオジの主張に今回ばかりは同意するよ
932デフォルトの名無しさん
2023/08/07(月) 00:47:42.86ID:uTLlh+jk >>929なんでO(1)で済むんですか?
そもそもデータ全体を連続領域に確保するんでしょ?
その延長する部分のヒープがもう埋まってたらデータ全部丸写しするしかないんじゃないですか?
大体そもそもデータを連続領域に確保して前からも後ろからも関係なくアドレス1発でアクセスもできて、その上データの追加もO(1)でできるとかなら無敵じゃないですか?
そんな魔法のよなメモリ管理できるハズないのでは?
そもそもデータ全体を連続領域に確保するんでしょ?
その延長する部分のヒープがもう埋まってたらデータ全部丸写しするしかないんじゃないですか?
大体そもそもデータを連続領域に確保して前からも後ろからも関係なくアドレス1発でアクセスもできて、その上データの追加もO(1)でできるとかなら無敵じゃないですか?
そんな魔法のよなメモリ管理できるハズないのでは?
933デフォルトの名無しさん
2023/08/07(月) 00:48:41.30ID:Lr/s88yL Vecって単純過ぎてデータ構造では扱わなかったりするのかな
ならし解析では最初に出てきそうなネタだけど
ならし解析では最初に出てきそうなネタだけど
934デフォルトの名無しさん
2023/08/07(月) 00:50:22.19ID:uTLlh+jk ああ、データの読み書きが一回あたりI(1)ですか
でも今データの追加は整数の桁数が一上がるごとに発生するんですよ?
あらかじめデータの桁数が不明でそれが難しいと言ってるじゃないですか
足し算のたびにコピー発生しますよ?
でも今データの追加は整数の桁数が一上がるごとに発生するんですよ?
あらかじめデータの桁数が不明でそれが難しいと言ってるじゃないですか
足し算のたびにコピー発生しますよ?
935デフォルトの名無しさん
2023/08/07(月) 00:53:46.05ID:O5oF7I6f こいつぅ
絶対わかってないやんw
絶対わかってないやんw
936デフォルトの名無しさん
2023/08/07(月) 00:53:52.95ID:++BmxY1A 実際バイナリスプリッティングでマクローリン級数で足し算する場合とかどうやってあらかじめ必要桁数予言するの
937デフォルトの名無しさん
2023/08/07(月) 00:54:45.54ID:eXrQj8ZH 実際どんな用途かも具体的に書いてるのに
938デフォルトの名無しさん
2023/08/07(月) 02:21:35.00ID:pearvhja 2年くらい前の過去スレと今の状況見比べて泣いちゃった
939デフォルトの名無しさん
2023/08/07(月) 10:50:23.98ID:wl/Lx6N5 ここまでvecdeq無しとは
940デフォルトの名無しさん
2023/08/07(月) 18:18:54.25ID:UTlzilSe VecDequeもその名の通りVec(正確にはどちらもRawVec)で作られていて
確保されている連続領域に対して未使用領域が末端か途中かの違いしかない
>>932は確保されている連続領域が埋まった時のコストを気にしているようだが
サイズNが埋まるまでの再配置の総コストは最悪ケースでもわずかN-1回の読み書きコストで済む
例えばサイズN/2が埋まった時にその倍のサイズNの新たな連続領域へ再配置するためにはN/2回の読み書きが発生
仮に最悪ケースでサイズ1からスタートしてもそれまでの累積の再配置コストはN/2+N/4+N/8+...+1 = N-1が上限値となる
つまりサイズNが埋まるまでの再配置の総コストは最悪のケースで読み書きN-1回でありO(N)で済む
一方でサイズNが埋まるまでの再配置以外の読み書きが何回行われるかを今回のケースで考えると
次々とサイズが倍々に増えていく計算の場合は最小でも合計O(N)回の読み書きが起こり
次々とサイズがリニアに増えていく計算の場合は最小でも合計O(N^2)回の読み書きが起こり
もっと緩やかにサイズが増える場合や上述の増え方の場合でも普通に読み書きが多い計算なら合計O(N^2)を超える
現実のほとんどの計算においてVecの再配置コストO(N)は誤差となる
確保されている連続領域に対して未使用領域が末端か途中かの違いしかない
>>932は確保されている連続領域が埋まった時のコストを気にしているようだが
サイズNが埋まるまでの再配置の総コストは最悪ケースでもわずかN-1回の読み書きコストで済む
例えばサイズN/2が埋まった時にその倍のサイズNの新たな連続領域へ再配置するためにはN/2回の読み書きが発生
仮に最悪ケースでサイズ1からスタートしてもそれまでの累積の再配置コストはN/2+N/4+N/8+...+1 = N-1が上限値となる
つまりサイズNが埋まるまでの再配置の総コストは最悪のケースで読み書きN-1回でありO(N)で済む
一方でサイズNが埋まるまでの再配置以外の読み書きが何回行われるかを今回のケースで考えると
次々とサイズが倍々に増えていく計算の場合は最小でも合計O(N)回の読み書きが起こり
次々とサイズがリニアに増えていく計算の場合は最小でも合計O(N^2)回の読み書きが起こり
もっと緩やかにサイズが増える場合や上述の増え方の場合でも普通に読み書きが多い計算なら合計O(N^2)を超える
現実のほとんどの計算においてVecの再配置コストO(N)は誤差となる
941デフォルトの名無しさん
2023/08/09(水) 00:49:09.66ID:52BV6d5f942デフォルトの名無しさん
2023/08/09(水) 18:58:03.94ID:2XWtgL1F でも競プロでvec.insert(0, value)でタイムアウトしたけどvecdeque.pushfront(value)ではタイムアウトしなかった経験があるな
943デフォルトの名無しさん
2023/08/09(水) 19:31:59.29ID:X5pmvNGk VecDequeはring bufferだから連続性は保証されないね
VecみたいなDerefがないから&[T]に渡せない
slice未実装かと思ったら2つのsliceで返すas_slices()が実装されてて思ったより芸が細かかった
VecみたいなDerefがないから&[T]に渡せない
slice未実装かと思ったら2つのsliceで返すas_slices()が実装されてて思ったより芸が細かかった
944デフォルトの名無しさん
2023/08/09(水) 22:17:02.23ID:5oPtG5Gl945デフォルトの名無しさん
2023/08/10(木) 04:07:06.41ID:GpbD/XFE >slice未実装かと思ったら2つのsliceで返すas_slices()が実装されてて
He-
He-
946デフォルトの名無しさん
2023/08/10(木) 04:08:51.37ID:GpbD/XFE vecdequeはlinkedlistじゃね
947デフォルトの名無しさん
2023/08/10(木) 06:08:17.32ID:74A6gUuN vecdequeはもちろんvecで構成
linkedlistは他のデータ構造(vector, binary tree, hash table)と比較してほとんどの用途で遅く不利なため極限られた用途でしか用いられない
linkedlistが用いられる限られた用途でもlinkedlistの欠点を補うため同時にhash tableやbinary treeなどと組み合わせて用いられることも多い
linkedlistは他のデータ構造(vector, binary tree, hash table)と比較してほとんどの用途で遅く不利なため極限られた用途でしか用いられない
linkedlistが用いられる限られた用途でもlinkedlistの欠点を補うため同時にhash tableやbinary treeなどと組み合わせて用いられることも多い
948デフォルトの名無しさん
2023/08/11(金) 08:01:08.13ID:4oMIZBsG949デフォルトの名無しさん
2023/08/11(金) 08:22:37.37ID:6e7vDYNE RustやるならCSでもまず計算モデル(特にスタックフレームモデル周辺)だろ。
950デフォルトの名無しさん
2023/08/11(金) 08:37:22.11ID:/t3LBfIN >>948
その配列というのが長さと場所を固定した連続領域を取るデータ構造なのよ
Vecは同じ連続領域だけど長さと場所は可変なデータ構造
VecDequeはVecを用いたリングバッファで連続領域を確保して使っているけど使用データ自体は最大二つの領域に分かれるデータ構造
LinkedListは連続領域を使わない連結リストといったようにいろいろあるデータ構造の中で質問者はどれを使うべきか悩んでるみたい
その配列というのが長さと場所を固定した連続領域を取るデータ構造なのよ
Vecは同じ連続領域だけど長さと場所は可変なデータ構造
VecDequeはVecを用いたリングバッファで連続領域を確保して使っているけど使用データ自体は最大二つの領域に分かれるデータ構造
LinkedListは連続領域を使わない連結リストといったようにいろいろあるデータ構造の中で質問者はどれを使うべきか悩んでるみたい
951デフォルトの名無しさん
2023/08/11(金) 11:19:59.50ID:4oMIZBsG 最近おかしな議論が複数のスレにまたがって続いてるけど
多倍長整数というワードすら出てこないんだからなあ
多倍長整数というワードすら出てこないんだからなあ
レス数が950を超えています。1000を超えると書き込みができなくなります。
ニュース
- 【無言】中国怒らせた高市首相→1週間だんまり、国民に実害も説明なし 中国問題を避けてスルー… ★4 [BFU★]
- 【いちご高騰】ヤマザキのクリスマスケーキ、いちご無し販売 [おっさん友の会★]
- 【日中対立】 朝日新聞のタイトル修正が中国逆ギレの火種か SNSで批判相次ぐ [♪♪♪★]
- ネット殺到「高市総理の責任」「完全に高市リスク」「負けるな」中国が水産物輸入停止→流石に総理批判の声も「どう責任取る?」 ★10 [樽悶★]
- 【音楽】『日本レコード大賞』各賞発表! 大賞候補にILLIT、M!LK、ふるっぱー、幾田りら、アイナ、ミセスら… 作詩賞は指原莉乃 [冬月記者★]
- 「ドラゴンボール」初の全世界キャラクター人気投票が開幕!212キャラからナンバーワンが決まる!! [ひかり★]
- 中国、レアアース輸出制限wwwwwwwwwwwwwwwwwwwwwwww🎌 [329329848]
- 【訃報】日経平均先物逝く、円安株安債券安 [943688309]
- 死ぬ直前に見たくないもの
- マッサージ師だが
- 【すべてが】𝗮𝗺͜𝗮͉𝘇𝗼𝗻ブラックフライデーSALE総合【いいだろ!】 [194819832]
- 【急募】中国の経済制裁に対抗して日本が切れるカード [163661708]
