X



Rust part14
レス数が1000を超えています。これ以上書き込みはできません。
0001デフォルトの名無しさん
垢版 |
2022/02/12(土) 01:24:16.59ID:XYE+Rws6
公式
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/

※Rustを学ぶ際に犯しがちな12の過ち
https://dystroy.org/blog/how-not-to-learn-rust

※Rustのasyncについて知りたければ「async-book」は必読
https://rust-lang.github.io/async-book/

※C++との比較は専用スレへ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/

※次スレは原則>>980が立てること

前スレ
Rust part13
https://mevius.5ch.net/test/read.cgi/tech/1636247099/
0002デフォルトの名無しさん
垢版 |
2022/02/12(土) 01:27:40.45ID:aHobc4uM
Rust The Book (日本語版)
https://doc.rust-jp.rs/book-ja/
Rust edition guide (日本語版)
https://doc.rust-jp.rs/edition-guide/
Rust by example (日本語版)
https://doc.rust-jp.rs/rust-by-example-ja/
Rust cookbook (日本語版)
https://uma0317.github.io/rust-cookbook-ja/
Rust API guideline (日本語版)
https://sinkuu.github.io/api-guidelines/
Rust nomicon book (日本語版)
https://doc.rust-jp.rs/rust-nomicon-ja/
Rust WASM book (日本語版)
https://moshg.github.io/rustwasm-book-ja/
Rust embeded book (日本語版)
https://tomoyuki-nakabayashi.github.io/book/
Rust enbeded discovery (日本語版)
https://tomoyuki-nakabayashi.github.io/discovery/
0004デフォルトの名無しさん
垢版 |
2022/02/12(土) 13:48:10.54ID:kNBFVDwU
新スレ乙です

前スレ994流れてたので
(以下引用)
struct S;
impl Drop for S {
fn drop(&mut self) {
println!("drop");
}
}
fn main() {
S;
}
↑じゃあこれは何が所有権をもってて何がdropさせてんの?
インスタンス説のほうがまだシックリくる?
変数も所有権を持てるしスコープ終了で手放せる?
(以上引用)

この場合はmain内の
S;
のところに隠れた一時変数がいて
{ let _s = S; }
みたいに変換されると考えれば自然だと思う
0005デフォルトの名無しさん
垢版 |
2022/02/12(土) 13:53:07.63ID:qPU2UgbF
前スレ>>994
匿名の一時変数(temporary)が所有者になってenclosing scopeを抜ける時にdropが呼ばれる

公式の見解とは違うけど変数じゃなくスコープが所有者になるという捉え方のほうが分かりやすければ別にそれでもいいと思う
実装的にはその方が近い
0007デフォルトの名無しさん
垢版 |
2022/02/12(土) 16:30:44.26ID:v8ccrYYP
>>4 >>5
それで正解。

所有権については公式がこう↓うたってんだから、値だとかインスタンスだとかいってる奴は公式に文句言えと。

4.1. What is ownership?
(ttps://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)

Ownership Rules

First, let’s take a look at the ownership rules.
Keep these rules in mind as we work through the examples that illustrate them:

* Each value in Rust has a variable that’s called its owner.
* There can only be one owner at a time.
* When the owner goes out of scope, the value will be dropped.
0008デフォルトの名無しさん
垢版 |
2022/02/12(土) 16:59:30.70ID:v8ccrYYP
非同期のデファクトライブラリはtokioかと思うがasync-std使ってる人おる?
0010デフォルトの名無しさん
垢版 |
2022/02/12(土) 23:26:08.10ID:/iL1/Dd6
>>5
同感
変数に入れないまま関数の戻り値となったり
その関数の戻り値が変数に入れないまま式の中で消費もしくは移動することが多い
そしてdropタイミングはスコープを抜ける時
だから変数よりもスコープが所有権を持っていると考えた方がより近いとの考えに同意する
ただし同じスコープ内で別変数へ移動させた場合もスコープ視点では移動なしとなる
それはdropに関して全く問題ないが変数間の移動を表現しきれていない

一方で属する変数もスコープも移動により次々と移り変わって行く
だから所有権と1対1でリンクしていて不変なものはインスタンスだというのも納得できるしそれ自体は正しく確定
ただし所有権と1対1でリンクしているインスタンス自体も移動していくからその移動を表現しきれていない

したがって
『所有権と1対1でリンクしているのは当然インスタンスとしつつも
そのインスタンスが代入や式や戻り値で使われるたびに変数もしくは見えない一時変数に必ず入っていると考え
さらにその変数が属するスコープの中にインスタンスが毎回イドウすると考え
他へ移動されぬまま属するスコープが消滅するとインスタンス及びその1対1となる所有権も消滅する』
というのが正確なところなのであろう

ただしそれでは学習するには長すぎるから大幅に端折って>>7の定義で良いと思う
そして学習した後で端折ってある部分が上述の長い説明だと後で理解できれば十分なのではないだろうか
0011デフォルトの名無しさん
垢版 |
2022/02/12(土) 23:33:37.93ID:/iL1/Dd6
>>8
使っている

>>9
その議論を少し読んでみたけど
サポート続けるべきの声もある程度あるし
何らか用途ごとにもう少し抽象化したインタフェースを確立して両立利用できるようにすべき声もあるようだ
明るい未来になるとうれしい
0012デフォルトの名無しさん
垢版 |
2022/02/13(日) 09:35:24.39ID:ykPYhkFQ
見えない一時変数とか想像しなくても
オーナー変数がある場合は
* There can only be one owner at a time.
* When the owner goes out of scope, the value will be dropped.
で、無い場合は
* When the value ほにゃららタイミング, the value will be dropped.
と公式で書いてくれてたらスッキリなのにな
0013デフォルトの名無しさん
垢版 |
2022/02/13(日) 11:34:54.98ID:NHDjNJ0w
>>12
一時変数は想像上の産物ではないよ
リファレンスに変数の一つとして定義されてるし
どういう時に一時変数が作られるのかも定義されてる
The Bookに詳しく書いてないだけ
0014デフォルトの名無しさん
垢版 |
2022/02/13(日) 11:56:22.68ID:ykPYhkFQ
>>13
勉強になりました

https://doc.rust-lang.org/reference/variables.html
> A variable is a component of a stack frame, either a named function parameter,
> an anonymous temporary, or a named local variable.

https://doc.rust-lang.org/reference/expressions.html#temporaries
> When using a value expression in most place expression contexts,
> a temporary unnamed memory location is created and initialized to that value.
> The expression evaluates to that location instead, except if promoted to a static.
> The drop scope of the temporary is usually the end of the enclosing statement.

匿名一時変数は式の終わりでdropされそうやね
0016デフォルトの名無しさん
垢版 |
2022/02/14(月) 21:08:19.96ID:JD6MLhyb
外部ライブラリを使わずに
コマンドライン引数の処理を昔ながらのシェルスクリプト風に処理したい場合
こんな感じでいいのでしょうか?
let mut args = std::env::args().peekable();
let cmd_name = args.next().unwrap();
let usage = || {
eprintln!("Usage: {cmd_name} [-d] [-q] [--] <target>");
std::process::exit(1);
};
let mut is_debug = false;
let mut is_quiet = false;
while let Some(b'-') = args.peek().and_then(|arg| arg.as_bytes().first()) {
let option = args.next().unwrap();
match option.as_str() {
"-d" => is_debug = true,
"-q" => is_quiet = true,
"--" => break,
_ => usage(),
}
}
if args.len() != 1 {
usage();
}
let target = args.next().unwrap();
もっと楽に記述できるよ、とか、もっと無駄を省けるよ、とか
何でもいいのでアドバイスお願いします
0017デフォルトの名無しさん
垢版 |
2022/02/15(火) 00:56:03.94ID:qT41k7yT
peekableにする意味ある?
手間かかってるだけに見えるし-o output.txtみたいなオプション引数も扱えなくならない?
0018デフォルトの名無しさん
垢版 |
2022/02/15(火) 16:20:56.03ID:yLJ5RfL8
look aheadのパターンにしたかったのかな
Peekableならnext_ifがいい感じにはまりそう

...
let mut is_debug = false;
let mut is_quiet = false;
while let Some(option) = args.next_if(|s| s.starts_with("-")) {
match option.as_str() {
"-d" => is_debug = true,
"-q" => is_quiet = true,
"--" => break,
_ => usage(),
}
}
if args.len() != 1 {
usage();
}
...
0020デフォルトの名無しさん
垢版 |
2022/02/15(火) 22:42:34.06ID:57mqcwZM
ところで
>>16の as_bytes().first() と
>>18の s.starts_with("-") はどっちが速いのかな?
今回は誤差として例えば数万行のテキストで#から始まるコメント行を除外したい場合
最善手は何?
0021デフォルトの名無しさん
垢版 |
2022/02/15(火) 23:44:22.03ID:je481k6i
どちらも文字列の先頭数byte参照するだけだから大差ないよ
as_* じゃなくて to_* を使うとかだと差が出るかもね
0023デフォルトの名無しさん
垢版 |
2022/02/16(水) 18:46:05.60ID:4BNkCNLv
>>20
他にも色々方法がある
例えば落とし穴だが一番表記が短いスライス &(&s)[..1]
ただし空行をs.len()で回避した場合でも
if "#" == &(&s)[..1] { これは先頭が非ASCIIだとpanicなので注意
utf8境界を見極めて最初の1文字を取り出すには面倒で
if "#" == &(&s)[..s.char_indices().nth(1).unwrap().0] { となり本末転倒
なので最初の1文字を取り出すには普通はイテレータchars()を使って
if Some('#') == s.chars().next() { となるが
今回は正しく先頭1文字ではなく先頭1バイトを取り出せれば判断できるので
if Some(b'#') == s.bytes().next() { の方が速い
しかしイテレータを使うまでもないから
if Some(&b'#') == s.as_bytes().get(0) { と配列アクセスでも十分だろう
先頭は需要が大きいためなのか
if Some(&b'#') == s.as_bytes().first() { と専用メソッドが用意されてるようだ
ただしここでもサボって
if b'#' == s.as_bytes()[0] { とすると空行でpanicするので注意
以上ここまでは先頭取り出し系だがシンプルに
if s.starts_with("#") { が一番わかりやすい
ただしこれは実装でinline指定がないから不利で遅いかもしれない
inlineで&[u8]に読み替えるだけの as_bytes() は確実に速い
あとは get(0) と first() がどちらもinlineでコードが
前者が if self < slice.len() { unsafe { Some(&*self.get_unchecked(slice)) } } else { None }
後者が if let [first, ..] = self { Some(first) } else { None }
たぶん展開して最適化した最終コードは同じになるのではないか
そしてSomeやNoneは最適化で if Some(&b'#') == 部分と反応しておそらく消えると予想しているが
if let [b'#', ..] = s.as_bytes() { と最初からOption使わなければその点も確実という結論か
あとはみんなでツッコミしてくれ
0024デフォルトの名無しさん
垢版 |
2022/02/17(木) 10:37:24.58ID:nN2LTJ+a
premature optimizationの典型例
このレベルの最適化が本当に必要ならまずは計測しろ
0026デフォルトの名無しさん
垢版 |
2022/02/17(木) 11:01:53.16ID:W9idHeI8
結論の if let [b'#', ..] = s.as_bytes() { なら可読性も落ちず意味もわかりやすいからいいんじゃね?
それを満たした上で長さが0でないことと先頭バイトの定数比較コードになると誰もが予測可能
0027デフォルトの名無しさん
垢版 |
2022/02/17(木) 11:06:38.82ID:reqFguXW
うーんRustのデフォルトがムーブになっているのはおもしろいな
かなり思い切った設計をしている
0030デフォルトの名無しさん
垢版 |
2022/02/17(木) 23:06:37.97ID:S7RVNfva
あらためてRustは凄いな
enum Optionで意味わかりやすく安全にプログラミングしつつ
生成コードからはSomeやNoneが綺麗に跡形もなく消え去ってC言語で書いたときと同じになるんだな
0031デフォルトの名無しさん
垢版 |
2022/02/17(木) 23:36:39.74ID:JQNiobes
ML系言語の概念とC的な低レイヤの概念を融合した上で
オブジェクトの依存性の概念も付け加えるというのは実に素晴らしい考えだと私も思う。
個人的には Haskell が好きなんだけどランタイムサポートが重すぎると思ってたので Rust は大歓迎だ。
0032デフォルトの名無しさん
垢版 |
2022/02/17(木) 23:47:52.93ID:W9idHeI8
ヒープを使うか使わないかと
dynを使うか使わないかの2点だけは
コンパイラも最適化できないのでそれだけ気をつけていれば大丈夫
0034デフォルトの名無しさん
垢版 |
2022/02/18(金) 08:29:45.01ID:dvRY56uQ
>>33
BoxだけでなくVecやStringなどもヒープを使う
配列[T;N]や配列を使ったArrayVecやArrayStringなどはスタック上のみ使う
dynはBox<dyn ...>の形ならヒープ上だけど&dynの形ならスタック上のみで使うことができる
0036デフォルトの名無しさん
垢版 |
2022/02/18(金) 10:17:03.62ID:dvRY56uQ
>>35
例えば標準入力stdin()とファイルFile::open()は型がStdinとFileで異なるが
どちらもtrait Readを実装しているから&mut dyn Readに入れることで同じコードでreadできるようになる
このdyn Traitをtrait objectと言って動的ディスパッチとなるが生成コードは一つになる
ちなみにimpl Traitだとコンパイル時に静的に解決されて生成コードは型毎に多数のコードが生成される

trait objectは?Sizedだから直接は扱わずに&dynの形かBox<dyn>の形で使うことになる
&dynの形ならスタック上のみで使うことができるが元の型よりは長く生きられない制限がある
そこで例えば関数の返り値にしたい時などはヒープを使ってBox<dyn>の形にして返す
0037デフォルトの名無しさん
垢版 |
2022/02/18(金) 18:16:26.39ID:XJ022fQi
Box<T>の形ならヒープ上だけど
&Tの形ならスタック上のみで使うことができる

と言われたら、ん?ってならない?
0038デフォルトの名無しさん
垢版 |
2022/02/18(金) 18:18:33.56ID:QcWsB3dM
ヒープ使わないんだったら、そりゃスタックになるが、
そもそもなにか勘違いしてない?
0040デフォルトの名無しさん
垢版 |
2022/02/19(土) 02:35:40.94ID:l5YLFJyt
dynはヒープを使わない
しかしサイズが不定
つまりdyn型の変数はない
スタック上で使う時は&dyn型の変数に入れて用いる
戻り値にしたいならBox<dyn Trait>
これはヒープ使うことになる
0042デフォルトの名無しさん
垢版 |
2022/02/19(土) 13:30:36.11ID:Pa/XmNxa
>>40
strはヒープを使わない
しかしサイズが不定
つまりstr型の変数はない
スタック上で使う時は&str型の変数に入れて用いる
戻り値にしたいならBox<str>
これはヒープ使うことになる


これでも
んー・・・ってならないならもういいや
0043デフォルトの名無しさん
垢版 |
2022/02/19(土) 15:49:52.73ID:lVeS0ElI
その置き換えは無理があるんじゃないか
&strは単なる参照で&strの一部でもStringの一部でも代入できる
&dyn Traitはそれを実装する具体型を代入することで生成される
0044デフォルトの名無しさん
垢版 |
2022/02/19(土) 18:01:00.26ID:yRRevCPm
&dynの参照先はヒープ(例えばBoxの中身)の可能性もあるからヒープを使わないって表現は誤解を招きそう
0045デフォルトの名無しさん
垢版 |
2022/02/19(土) 18:59:15.30ID:l5YLFJyt
>>41
stable前提話でごめん
unsized localがstableとなるには
一旦可変長配列を切り離さないと厳しい?

>>44
そんなことを書いてる人はいない
俺が書いた分も、dyn自体は(arrayなどと同様に)ヒープを使わない、だけだぞ
しかもその後にBoxでヒープを使う話もしている
0046デフォルトの名無しさん
垢版 |
2022/02/19(土) 22:32:05.29ID:uI4ynUv+
>>43
&strがstrへの参照であるように
&dyn Traitもdyn Traitへ単なる参照
&strにStringを代入すればDerefがstrを生成してるように
&dyn ReadにFileを代入すればコンパイラがdyn Readを生成してる

BoxだけでなくRc<dyn Trait>とかも使えるからね
0047デフォルトの名無しさん
垢版 |
2022/02/19(土) 23:18:16.06ID:lVeS0ElI
>>46
自己矛盾を起こしているぞ2点も
まず1点目
前者はターゲットstrでimpl Deref for String実装というコードが実際にありその枠組みに従った規定通りの操作
後者はそのような枠組みも実装コードも公開されていない操作
次に2点目
前者はStringの一部を指しているだけであり何か新たな実体を生成してそこを指しているわけではない
後者はFileとは別にvtableなどの実体を生成している
このように明白に異なる
0048デフォルトの名無しさん
垢版 |
2022/02/20(日) 01:59:50.05ID:Fazun+uY
>>47
strとtrait objectという別のものなんだから違いがあるのは当たり前
>>40>>42の対比が成立しないと言えるような違いを指摘しないと意味ないよ
0049デフォルトの名無しさん
垢版 |
2022/02/20(日) 02:11:24.76ID:Fazun+uY
>>47
>前者はStringの一部を指しているだけであり何か新たな実体を生成してそこを指しているわけではない
>後者はFileとは別にvtableなどの実体を生成している

ああ、なるほど
trait objectが生成されるときにvtableも生成されると思ってるのか
0050デフォルトの名無しさん
垢版 |
2022/02/20(日) 02:49:14.40ID:Q+YkyZIv
dynにキャストするときにコンパイラがfat pointerから参照させる用のvtableを生成することを指しているのでは?
0051デフォルトの名無しさん
垢版 |
2022/02/20(日) 03:20:02.69ID:Y4d5gioW
>>48
そのように大きく違いのある全く別のものを対比させるのは無意味なので、置き換えは無理があるんじゃないか、と書いた

>>49
そこは実行時にvtableを生成とも誤解しかねない書き方をしてすまん
vtable自体は型とtraitのペアで静的に確定するものでありコンパイル時に生成している
0052デフォルトの名無しさん
垢版 |
2022/02/20(日) 10:31:39.82ID:NNOlvVsy
>>50,51
vtableはtrait objectの有無に限らずtrait実装につき1つコンパイル時に作成されそれが共有して使われる

vtableを指すtrait objectも実行時じゃなくコンパイル時に作成される
実行時にはvtable経由のダイナミックディスパッチが発生するだけ
0053デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:23:51.17ID:Q+YkyZIv
>>52
そうか、crate内で静的ディスパッチしかしてなくても他crateからtrait objectとして使われる場合もあるから常にvtableは生成されるのね

ちなみに、object safeでないtraitについては生成されない (できない) よね?
0055デフォルトの名無しさん
垢版 |
2022/02/20(日) 14:48:11.68ID:MpUmJclU
>>53
trait objectとして使われなくても常にvtableが作成されるかどうかはコンパイラの最適化の話だからここでは関係ないよね
実際のところはdylibじゃなければコンパイル時に使われないことがはっきりしてるはずだから作られないと思うけど
0056デフォルトの名無しさん
垢版 |
2022/02/20(日) 17:48:45.70ID:Q+YkyZIv
>>55
コンパイル時じゃなくてリンク時の最適化の話じゃないの
オブジェクトファイルには常にvtable埋め込まれてるのかと
それとも dyn Trait を使った側のcrateのオブジェクトファイルにvtableは埋め込まれる?
0057デフォルトの名無しさん
垢版 |
2022/02/20(日) 22:19:41.32ID:uSEnVnLU
>>51
>> vtable自体は型とtraitのペアで静的に確定するものでありコンパイル時に生成

>>52
>> vtableはtrait objectの有無に限らずtrait実装につき1つコンパイル時に作成

この件だがコンパイラのソースを見ると
必要となる型の分だけコンパイル時にvtableを作成してるよな
https://github.com/rust-lang/rust/blob/stable/compiler/rustc_codegen_ssa/src/meth.rs#L53
0060デフォルトの名無しさん
垢版 |
2022/02/21(月) 17:43:56.41ID:LC1rF3os
各型毎にtrait objectやvtableはこういう構造になっている
let mut stdin: std::io::Stdin = std::io::stdin();
let addr_stdin = addr!(stdin); // &mut借用する前にアドレスを得ておく
let dyn_stdin: &mut dyn std::io::Read = &mut stdin; // ここで dyn Readのtrait object作成
assert_eq!(val!(addr!(dyn_stdin), 0), addr_stdin); // 前半は元のstdinを指している
// assert_eq!(val!(addr!(dyn_stdin), 1), 【Stdin用のvtable】); // 後半はStdin用vtableをを指している
assert_eq!(val!(val!(addr!(dyn_stdin), 1), 3), <std::io::Stdin as std::io::Read>::read as usize);
assert_eq!(val!(val!(addr!(dyn_stdin), 1), 4), <std::io::Stdin as std::io::Read>::read_vectored as usize);

別の型でも同じようにdyn Read作成
let mut file: std::fs::File = std::fs::File::open("/dev/null").unwrap();
let addr_file = addr!(file);
let dyn_file: &mut dyn std::io::Read = &mut file; // trait object作成
assert_eq!(val!(addr!(dyn_file), 0), addr_file); // 前半は元のfileを指している
// assert_eq!(val!(addr!(dyn_stdin), 1), 【File用のvtable】); // 後半はFile用vtableをを指している
assert_eq!(val!(val!(addr!(dyn_file), 1), 3), <std::fs::File as std::io::Read>::read as usize);
assert_eq!(val!(val!(addr!(dyn_file), 1), 4), <std::fs::File as std::io::Read>::read_vectored as usize);
上述Stdinの時と同じ位置にFile用のread()やread_vectored()がvtableに入っていることがわかる

したがって>>59>>51が正しいと思う
各trait毎にvtableのメソッドの位置が決まり
そのtraitを実装する各型毎にvtableが作成される
0061デフォルトの名無しさん
垢版 |
2022/02/21(月) 18:18:27.01ID:Vy+crfrM
traitをimplした型が違ったら対応するfnの中身も違うので
同じtraitでも実装された型ごとに違うvtable作らなきゃいけないのは確かに当然か

>>60
異なるcrateからtrait object生成した場合にvtableは同じアドレスのものになるの?
それとも、異なるものになるの?
0062デフォルトの名無しさん
垢版 |
2022/02/21(月) 23:56:22.93ID:1opwFCgw
>>57
「trait objectを使うようなコードが一切存在しなくても」vtableが作られると言いたかったわけではないんだが書き方が悪かったね
0063デフォルトの名無しさん
垢版 |
2022/02/22(火) 00:04:11.51ID:DlNWIu8c
vtable自体はデバッグビルドのasmやllvm-irで確認できるよ
例えばxという名前のメソッド1つだけ持つFooトレイトのi32実装ならこんな形でvtableが出力される

.quad core::ptr::drop_in_place<i32>
.asciz "¥004¥000¥000¥000¥000¥000¥000¥000¥004¥000¥000¥000¥000¥000¥000"
.quad <i32 as playground::Foo>::x
0064デフォルトの名無しさん
垢版 |
2022/02/22(火) 11:55:50.79ID:M+NPwtu0
>>61
crateごとじゃなくcodegen unitごとにvtableが作成される可能性が一応ある
crateが違っても必ずしも複数のvtableができるわけではない
0066デフォルトの名無しさん
垢版 |
2022/02/22(火) 12:36:19.01ID:Uj7UhjXB
>>64
前者は分かるんだけど後者はどういう時にそうなるの?
依存crateにvtableが含まれてる場合?
0067デフォルトの名無しさん
垢版 |
2022/02/22(火) 14:56:23.72ID:S7d5HFwX
>>60
もう少しvtableの情報を詳細にした
let mut file: std::fs::File = std::fs::File::open("/dev/null").unwrap();
let addr_file = addr!(file);
let dyn_file: &mut dyn std::io::Read = &mut file;
という状況で以下が成立

assert_eq!(val!(addr!(dyn_file), 0), addr_file);
let vtable_file = val!(addr!(dyn_file), 1);
assert_eq!(val!(vtable_file, 0), std::ptr::drop_in_place::<std::fs::File> as usize);
assert_eq!(val!(vtable_file, 1), std::mem::size_of::<std::fs::File>());
assert_eq!(val!(vtable_file, 2), std::mem::align_of::<std::fs::File>());
assert_eq!(val!(vtable_file, 3), <std::fs::File as std::io::Read>::read as usize);
assert_eq!(val!(vtable_file, 4), <std::fs::File as std::io::Read>::read_vectored as usize);
つまり型情報が消失したdynにおいてもこのvtableさえ保持していれば正しくトレイトメソッドやデストラクタを呼び出せる

>>65
そのコードだと比較しようとしているのはvtableやそのアドレスではなく
上述コードでのdyn_fileのアドレスを比較しているだけなのでそもそも前提が謎だな
さらにvtableの内容は各型に完全に依存しているからmergeの意味もよくわからない
0068デフォルトの名無しさん
垢版 |
2022/02/22(火) 15:27:07.33ID:Uj7UhjXB
空traitなんかは異なる型同士でvtable使い回しできるのでは
あとは全associated fnにデフォルト実装が与えられていて中身が全く同じものとか
いずれにせよLLVMがよしなに最適化してくれるとかなのでは?
0069デフォルトの名無しさん
垢版 |
2022/02/22(火) 17:06:00.72ID:S7d5HFwX
vtableにはデストラクタも乗ってるようだけどそれも必要ない場合あるもんな
>>67の状況も今後実装が変わったり最適化で消えたり色々ありうるわけだ
いずれにせよ我々は興味本位で語り合ってるだけであり
このあたりの非公開の仕様に依存したコードを書いてはいけないしな
0070デフォルトの名無しさん
垢版 |
2022/02/22(火) 23:08:55.74ID:uChpKE+n
>>67
>上述コードでのdyn_fileのアドレスを比較しているだけなのでそもそも前提が謎だな
Rc::ptr_eqで単純に比較するとfat pointer内のdataへのpointerとvtableへのpointerの両方が一致してるかのテストになる

>さらにvtableの内容は各型に完全に依存しているからmergeの意味もよくわからない
わかりやすいのは&Tと&mut Tのように可視性のみ違う場合
0072デフォルトの名無しさん
垢版 |
2022/02/22(火) 23:33:33.79ID:uChpKE+n
>>66
>依存crateにvtableが含まれてる場合?
そうだね
依存crateに含まれてても同じ内容のvtableができる場合もあるみたいだからいくつか条件があるみたいだけど
0074デフォルトの名無しさん
垢版 |
2022/02/23(水) 08:40:05.57ID:jDTq074F
プロジェクトのディレクトリの外から
$ cargo run
するときってどうやってプロジェクト (ディレクトリ) を指定するの?
0077デフォルトの名無しさん
垢版 |
2022/02/23(水) 23:58:29.92ID:EqZ7VJsi
>>70
vtableがmergeされるのかどうか
trait定義methodの定数返しと最適化されやすいようにして
さらに &T と &mut T でやってみたがtableは別々になった

まず最初の原因はvtable最初の要素である以下が成立していないためとわかった
assert_eq!(std::ptr::drop_in_place::<&i32> as usize, std::ptr::drop_in_place::<&mut i32> as usize);
ところが--releaseにすると上記は成立するようになった
同様にtrait定義methodも--releaseにすると同じアドレスとなった
つまりこういう実験において--releaseオプションは必須
そしてvtableの内容は全て完全に一致
しかしvtableのアドレス(格納場所)は異なり別々のvtableのままであった
0078デフォルトの名無しさん
垢版 |
2022/02/24(木) 00:46:54.35ID:rseQo+7Q
LLVMの最適化で何が行われるかrust側では保証できないから >>65 みたいに同一性について保証しないって仕様になっているんだろうね
0079デフォルトの名無しさん
垢版 |
2022/02/24(木) 00:52:17.43ID:8HElZ5AU
そういえばRustってC++とかFortranみたいに最適化で結果変わる可能性ってあるの?
0081デフォルトの名無しさん
垢版 |
2022/02/24(木) 00:59:33.72ID:8HElZ5AU
>>77は内部構造が変わるという話で出力が変わるという話ではないと思っていた
0082デフォルトの名無しさん
垢版 |
2022/02/24(木) 01:53:13.93ID:9O+r6lMK
>>79
Rustは他の言語と違い、UB (undefined behavior)すなわち未定義動作を基本的に起こさないように安全に設計されている
最適化オプションの有無でもその点は大丈夫

もちろん念のためだが、入力が異なれば結果は変わるし、非同期の実行タイミングは当然保証されないから実行順序に依存するコードは結果が変わり得る
そういうことでないならば結果は同じになる

ちなみにvtableの件は仕様が公開すらされていない内部情報の話
しかもそこに収容される関数のアドレスの値やvtableのアドレスの値というプログラマーが全く気にする必要ない話
だからこれらは変化してももちろん良くてそれを承知の上で盛り上がってるだけ
0083デフォルトの名無しさん
垢版 |
2022/02/24(木) 01:56:10.31ID:8HElZ5AU
>>82
よかった。安心したわ。ありがとう
0092デフォルトの名無しさん
垢版 |
2022/02/25(金) 17:28:20.31ID:kxjR7eze
同じやつかもしれんが、スレ違いの指摘を聞かない馬鹿3名引き取ってくれ
ID:u7rOKKj6
ID:iu2arc+w
ID:aDhOSI3t
0094デフォルトの名無しさん
垢版 |
2022/02/25(金) 17:39:52.83ID:q7+lZsL0
rustのバージョンごとのリリース予定機能ってどこかにまとまってるの?
betaに入ったものはだいたいそのままstableになるから事前にどの機能が来るのか分かると思うんだが
いつもstableリリースのブログ投稿で知るので、もっと早めに知れると嬉しい
0095デフォルトの名無しさん
垢版 |
2022/02/25(金) 18:25:23.29ID:clIznFGF
Rust コンパイラのリリースサイクルは六週間という時間で区切ってるから
その時点で確定してるものが入るって感じじゃないの。
次のリリースまでにこれとこれを……というようなマイルストーン方式ではない。
0096デフォルトの名無しさん
垢版 |
2022/02/25(金) 18:45:09.48ID:q7+lZsL0
最近12週間でnightly(master)でstabilizeされた機能一覧とか
最近6週間でbetaに入った機能一覧を知る方法ない?って意図だった
0100デフォルトの名無しさん
垢版 |
2022/03/02(水) 12:22:44.66ID:Pojz7Ujc
Electronの代替を目指す軽量なRust製フレームワーク「Tauri」、リリース候補版に到達
https://www.publickey1.jp/blog/22/electronrusttauri.html


Electronの優れた特徴を備えつつ、よりメモリ消費量が小さくファイルサイズもコンパクトで、高いセキュリティを備え、柔軟なライセンスを実現しようと開発されたのが「Tauri」です。

GitHubにはElectronとの比較表が示されています。それによるとLinux版のインストールサイズがElectronで52.1MBのところ、Tauriは10分の1以下のわずか3.1MB。同じくLinux版でのメモリ消費量はElectronが462MBのところ、Tauriは半分以下の180MBとなっています。

起動時間もElectronの0.80秒に対してTauriは0.39秒です。
0101デフォルトの名無しさん
垢版 |
2022/03/02(水) 13:09:17.24ID:f02FsuUz
モバイル版も予定されてるとなるとFlutterにも似てるかな
あっちはモバイルベースのフレームワークだけど
0103デフォルトの名無しさん
垢版 |
2022/03/02(水) 16:53:15.47ID:Bz8WDQhq
プロセス間だとCと大して変わらないと思う
libcのmmapとかでアドレスに共有ファイルを割り当ててそのポインタをBoxもどきで包む
Drop時にfreeじゃなくmunmapするBoxっぽい別の型が必要でプロセス間のロックとか考えるともっと面倒くさい
mmapでcrate検索すれば使えるのがあるかもしれない
0104デフォルトの名無しさん
垢版 |
2022/03/02(水) 17:43:29.63ID:uPKvDIET
基本的には >>103 の言うとおり C と変わらないと思う
shared_memoryというLinuxとWindowsで使えるクロスプラットフォームなcrateもあるみたいだね

ただプロセス間でメモリを共有する場合に複数プロセスから同一領域に対して &mut 参照を作っちゃうと UB にならないかは気になる
0107デフォルトの名無しさん
垢版 |
2022/03/03(木) 07:53:58.47ID:XBGsBJa3
むしろ、rustでプロセス間通信をする場合に相性が良いのは何か、というのが本質では無いだろうか?
プロセス間共有メモリをrust的に安全になるように包むことは可能なのか?
パイプやソケットの再実装にならないか?
0108デフォルトの名無しさん
垢版 |
2022/03/03(木) 08:16:43.34ID:yxmIabOi
本当に共有メモリが必要なのか?って所だよな
ベアメタル開発時のハードウェアみたいに必須のケースもあるけど
0109デフォルトの名無しさん
垢版 |
2022/03/03(木) 08:44:34.78ID:y+9ANsMY
メッセージキューのほうが安全かね。
速度と手間は犠牲になりそうだけど。
0110デフォルトの名無しさん
垢版 |
2022/03/03(木) 09:15:37.98ID:yKQiCvPK
どういう問題を解決したいかという文脈抜きに
どういう手段がいいかを論じても意味ないよ
いわゆるXY problem
0111デフォルトの名無しさん
垢版 |
2022/03/03(木) 09:18:31.12ID:QJbsAkty
>>107
共有メモリをミューテクスで排他制御するならロックの取得/解放をメモリの取得/解放と同等に扱えるような気はするが
0113デフォルトの名無しさん
垢版 |
2022/03/03(木) 16:55:17.18ID:/KrGueou
>>112
volataileはプロセス間のリソース共有とは概念的には別の話。
0114デフォルトの名無しさん
垢版 |
2022/03/03(木) 17:16:17.86ID:P+eyfKB6
少なくともCでは
CON02-C. volatile を同期用プリミティブとして使用しない
ttps://www.jpcert.or.jp/sc-rules/c-con02-c.html
だけど、Rustは同期が保証されるんだっけ?
0116デフォルトの名無しさん
垢版 |
2022/03/03(木) 19:15:45.62ID:hTxF5AaQ
全ての共有メモリのページアクセスに対して割込みをかけてるならそういう実装も可能だろうけど、現実的には考えにくいだろうw
アホなこと考える前に自分でコード読めよw
0121デフォルトの名無しさん
垢版 |
2022/03/04(金) 20:47:25.90ID:4zB49VIz
Rustみたいな標準ライブラリが未熟で安全性のかけらもなく、野良のゴミコードばかりの言語ありがたがって使うアホいないよなw
0123デフォルトの名無しさん
垢版 |
2022/03/04(金) 20:57:54.90ID:4zB49VIz
20年くらい前のJavaはSunの強力な後押しでつよつよだったからなw
ソフト資産も順当に増えたw 安全性はRustの比じゃないし、らいとわんすらんえびうぇあと嘯いてたw
0124デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:04:31.08ID:e8gLPWot
>>123
たしかにヌルポなどJavaの安全性は低いけど
RustはJavaとは異なりその点も安全性が保証される言語だから
実際にJavaからRustへの移行も進んでいる
0125デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:06:23.95ID:4zB49VIz
ぬるぽなどの安全性!?ぬるぽなんて安全そのもので代名詞みたいなもんだろうw
0128デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:15:18.91ID:2tyOtSaX
>>124
それ以外にもJavaは実行時エラー(例外)が多すぎですね
Rustはコンパイル時にエラー検出してくれるものが多いだけでなく
実行時エラーとなるものでもResultやOptionで返すからエラー処理忘れが起きないけど
Javaは忘れていても通ってしまい実行時にレア発生するものだと本運用で例外発生で落ちたり
0130デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:20:22.36ID:4zB49VIz
そんなこと起きないし
Rustみたいに
誰もコーディングできません
聞ける人いません
ライブラリありません
エラーわかりません
とか言われないw
0133デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:33:51.78ID:4zB49VIz
どんな言語でもロジックミスでプログラムが終了することはいくらでもあるw
安全というのはそういう事態が起きてもプログラムがsegmentation faultなどで落ちないことw
よりよい実装方法はあるけど、それはそれw
まあリリース後にpanicで終了するのは製品ならやばいw
0134デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:47:04.33ID:2tyOtSaX
>>132
可能な限りunwrap()は避けたほうがよいでしょう
もちろん続行不可能なために意図的にpanic終了させたい場合は別です
ロジック的にここでは絶対にNoneやErrが来ないはず!(と思い込んでいる)ケースもありますが
それならばせめてその理由を記述したexpect()を呼ぶように変えることで
発生時対処やコードをレビューする人にも役立つと思います
0136デフォルトの名無しさん
垢版 |
2022/03/04(金) 21:57:04.53ID:2tyOtSaX
もちろん誰が見ても起きないとわかる自明な場合はunwrap()でいいと思いますよ
自明でない場合はせめてコメントに理由を残すとよいでしょう
自分で書いたコードでも1年後に「ここでunwrap()大丈夫だっけ?」と忘れてることもありうるためw
0137デフォルトの名無しさん
垢版 |
2022/03/04(金) 22:05:29.47ID:4zB49VIz
そんなのは誰がどんな理由でどう書いたってその人の自由w
他の人がどう思うかを気にするなら、べき論くらいは知っててもいい程度の話w
0138デフォルトの名無しさん
垢版 |
2022/03/04(金) 22:05:29.91ID:yoTd6F0f
unwrapはunwrapで死ぬけどヌルポはしばらく動いてから死ぬという地味な怖さがある
0143デフォルトの名無しさん
垢版 |
2022/03/04(金) 23:14:03.66ID:rsYyHWe+
もしかして手元のCコードをRustにベタ移植してる?

コンパイル通すためにunsafeこんもりなら納得できるが
0146デフォルトの名無しさん
垢版 |
2022/03/05(土) 00:22:29.41ID:6Mx0EdLs
すまん。セグフォする言語使ってる雑魚おる?
0148デフォルトの名無しさん
垢版 |
2022/03/05(土) 02:38:11.66ID:S5Q/+OCY
何ヶ月か前にもいたな。Rustのいう安全とは何かを知る気が一切無いまま、安全じゃないって煽ってたやつが
0149デフォルトの名無しさん
垢版 |
2022/03/05(土) 02:50:45.20ID:AqnMHu7I
Rustはunsafeを隠蔽し、しかも内包する動機を安全の核とする部分に持つ劇的矛盾言語w
それを安全安全高速と謳って騙ってベアメタル領域に行ってみたり、他スレまでしゃしゃり出るうざさw
マジで迷惑w
firefoxだけで使って大人しくしとけw
0151デフォルトの名無しさん
垢版 |
2022/03/05(土) 03:55:08.77ID:AqnMHu7I
俺が出したやつじゃんw
あのときも言ったけど、その辺の巨人は必要のあるニッチな領域を持ってるからバックにいるだけw
あのときからマジでRust推しがウザすぎてRust推すのやめたんだよなw
0154デフォルトの名無しさん
垢版 |
2022/03/06(日) 00:17:17.68ID:ea3LwkPH
tauri触ってみたけどRust⇔JSの値のやりとりはJSON限定なのかな
Responseのbodyにバイナリデータ入れて返す方法を探してるけど
iframe内で送受信するオプションがあるからできないかもしれない
0156デフォルトの名無しさん
垢版 |
2022/03/06(日) 12:07:19.24ID:ea3LwkPH
154だけどBuilderのregister_uri_scheme_protocolでいけそう
WebViewのIPCをちょっと勘違いしてた
0157デフォルトの名無しさん
垢版 |
2022/03/06(日) 12:57:45.63ID:oRBcPyqI
全く使ってないけど結局js使うんならややこしくなるだけだろw
electronでwasm使ってウンウン唸ってる層にしか刺さらないように見えるのに宣伝うるさすぎw
しかもRust推しの数字操作は常にえげつないw
実効果と桁が違う宣伝効果をタイトルに持ってきちゃうw 詐欺かよw
0158デフォルトの名無しさん
垢版 |
2022/03/06(日) 13:11:37.97ID:oRBcPyqI
js周りで言えばdenoとか最近どうなん?
わざわざ作り直した挙げ句、「全然速くなってませんでした!!!!少し設定とか出来るから許して…てへw」では困るだろw
いろいろ足りない処理もあるし、ベンチ向けに偏りすぎてると思うけど、後発ならjust-jsとか特定用途で高速化・コンパクト化できている
この差は何なんだろう?
0159デフォルトの名無しさん
垢版 |
2022/03/06(日) 14:19:43.76ID:XU+V9ZSH
denoってセキュリティ周りをどうにかするのがモチベーションで高速であることは謳ってないのでは
0160デフォルトの名無しさん
垢版 |
2022/03/06(日) 14:25:13.83ID:ea3LwkPH
>>157
内部処理もUI周りも全部同じ言語で書いた方が楽って層には敬遠されそうだけど
内部処理はRust、UI周りはHTML+JSの方が書きやすいって層には需要があると思う

electronはよく知らないけどWebViewはバイナリにブラウザ埋め込む感じだから
ブラウザ内でバイナリ実行するwasmとはあまり関係ないかも
0161デフォルトの名無しさん
垢版 |
2022/03/06(日) 15:17:04.79ID:oRBcPyqI
>>159
作者のモチベーションがどうというより、ユーザー視点だとわざわざ書き直したにしてはパッとしないってこと
しかも書きっぷりまで変わるんではちょっとね
V8の上側にRust入ってるのになぁ〜w

>>160
> 内部処理はRust、UI周りはHTML+JSの方が書きやすいって層
wasm使う層だよねw

> electronはよく知らないけどWebViewはバイナリにブラウザ埋め込む感じだから
> ブラウザ内でバイナリ実行するwasmとはあまり関係ないかも
埋め込むというかバイナリをくっつけるだけでしょw
包含関係が逆なだけで酷似してるし、問題も似たような問題ばかりw
wasmならwebでそのまま動くが、tauriだとplatform限定されてnativeな分Rust側の速度が速いってだけw
0162デフォルトの名無しさん
垢版 |
2022/03/06(日) 15:42:49.31ID:yex+Q2w4
Rustでそんな便利な状況になっているのか
tauriというのをちょっと試してみるかな
0163デフォルトの名無しさん
垢版 |
2022/03/06(日) 16:43:21.41ID:oq6skpEb
tauri自体うんぬんじゃなくて、electronクラスのメジャーミドルにまでRustでの書き換えが浸透してきてるってこと
すなわちRustがシステムプログラミングのデファクトスタンダードになったってことを表すエビデンスが1つ増えた
0164デフォルトの名無しさん
垢版 |
2022/03/06(日) 16:58:21.68ID:oRBcPyqI
逆だよw
electronはそもそもjsでアプリを書こうというものであって、ごく一部のクソメジャーアプリを除けばjsの範疇を出ないし、クソメジャーアプリはもうそれ自体がプラットフォームと化してるからカウントできないw
C#で書けば楽に何でも書けるのになんでわざわざHTML+JS+Rustを不自由なフレームまで使って書きたがるのか・・・ユーザーは不便、開発者も面倒とメリットなんて全くないのにw
結局ただの自己満足なんだよね
0165デフォルトの名無しさん
垢版 |
2022/03/06(日) 17:00:13.90ID:UG2ti1iI
C#ってMacとLinuxでまともに動かなくね
0169デフォルトの名無しさん
垢版 |
2022/03/06(日) 17:56:46.74ID:oRBcPyqI
あちこちのスレで長期間スレ違い指摘を無視して嘘八百並べるRust推しがいたからでは?w
0170デフォルトの名無しさん
垢版 |
2022/03/06(日) 17:57:08.30ID:p8wz0iuX
>>167
やっかみだろ
書けない人には絶対書けない言語だしな
C/C++もそうだがJSちょっとかじった程度のスクリプトキディが書ける言語ではないと言う認識を持ってほしいね
0172デフォルトの名無しさん
垢版 |
2022/03/06(日) 17:58:38.02ID:oRBcPyqI
その辺の言語は普通にかけるけどなw
Rustが安全とか嘯くアホよりはマシだと思うぞw
0173デフォルトの名無しさん
垢版 |
2022/03/06(日) 18:02:20.15ID:p8wz0iuX
Rust書けるようになるためにはまずGC言語への依存を捨てろ
自力でメモリ管理できる能力が絶対に必要
スタック、ヒープ、Dropトレイト、所有権、借用ルール、(可変参照と不変参照)、Box、arena、Rc、Cell、RefCell
この辺り曖昧さなく完全に理解してないと書けない言語なの
無能にはかけない言語
0175デフォルトの名無しさん
垢版 |
2022/03/06(日) 18:06:38.47ID:p8wz0iuX
Rustは悲惨な言語だよ
JS書いてブイブイ言わせてるようなやつが全く赤子みたいになるんだからw
0180デフォルトの名無しさん
垢版 |
2022/03/06(日) 19:16:52.49ID:p8wz0iuX
>>173
追加
Derefトレイト、Copyトレイト、Cloneトレイト
こいつらは必ずしも必要ではないがメモリの使い方の訓練にはなるので触っておくべき
逆にこれらを理解できればRustは書ける
C#おじさんガンガレ
0181デフォルトの名無しさん
垢版 |
2022/03/06(日) 19:19:37.62ID:oRBcPyqI
アホだなw 俺はRustを書けないなどと一言も言ってないw
そしてC#おじさんとか意味不明な名前を付けられてる人でもないw
0190デフォルトの名無しさん
垢版 |
2022/03/06(日) 19:49:25.58ID:oRBcPyqI
>>188
最近はもうご無沙汰してるけどemacs使ってたよ

>>189
コンプレックスではなく、広めるメリットのないゴ○言語だよねって言ってる
0192デフォルトの名無しさん
垢版 |
2022/03/06(日) 20:04:53.65ID:yex+Q2w4
TauriをJavaScriptを一切書かずRustだけで使うのに挑戦し始めました
とりあえず公式に従いcargo利用パターンでやってみる
$ cargo install tauri-cli --locked --version ^1.0.0-rc
これで bin/cargo-tauri がインストールされて cargo tauri XXX が使えるようになった
$ cargo tauri init
これで src-tauri というディレクトリができて tauri.conf.json に指定すればよいのか

どうやらwasmを入れてやればTauri利用でもブラウザ利用でもRustコードだけで済むっぽい
$ rustup target add wasm32-unknown-unknown
$ cargo install trunk
$ cargo install wasm-bindgen-cli
これで bin/trunk などRustでのWASM使用環境が入ったようだ

次にフロントエンド用のディレクトリを作る
$ cargo new --bin frontend
$ cd frontend
ここで index.html を以下のdata-trunkを含む行でcssなど指定して適当に作成
<link data-trunk rel="css" href="/public/main.css"/>
$ trunk build
$ trunk serve
これでサーバーが起動された
まずはブラウザから http://localhost:8080/ により無コードwasm環境動作確認OK

これでようやくTauriに戻って先ほどの tauri.conf.json に今の分を記述
"devPath": "http://localhost:8080";,
"beforeDevCommand": "cd frontend && trunk serve",
"beforeBuildCommand": "cd frontend && trunk build",
$ cargo tauri dev
これで無事にTauriのウインドウがついに出てきた!ので無事に初期環境が成功
さてここからRustコードはどのフレームワークで書くのがおすすめ?
0193デフォルトの名無しさん
垢版 |
2022/03/06(日) 20:19:38.65ID:oRBcPyqI
>>191
どれもLispでそんな違いがあるとは思ってなかったし、そんな思い入れねーよ

>>192
wasm入れてpure rustは面白い試み
terminal作ってくれ
0194デフォルトの名無しさん
垢版 |
2022/03/06(日) 20:29:23.18ID:oq6skpEb
>>193
どれもLispでそんな違いがあるとは思ってなかったし、

なんだ素人だったwwwww
馬脚を表したなwww
0195デフォルトの名無しさん
垢版 |
2022/03/06(日) 20:32:44.98ID:aPFsI6mA
この人ぼくはプログラミングにはくわしいんだと
わめくほどボロが色々出て面白いな
0198デフォルトの名無しさん
垢版 |
2022/03/06(日) 20:53:26.84ID:yex+Q2w4
>>192の続き
とりあえずRust製フロントエンドフレームワークYewを使用
先程のfrontendディレクトリで
[dependencies]
yew = "0.19.3"
を Cargo.toml に追加して src/main.rs に以下のハローワールド記述
use yew::prelude::*;
fn main() {
yew::start_app::<App>();
}
#[function_component(App)]
pub fn app() -> Html {
html! {
<div>
<h2 class={"heading"}>{"ハローワールド!"}</h2>
</div>
}
}
そしてTauri側で再び
$ cargo tauri dev
無事にTauriでハローワールド!が出ました
同様にブラウザから http://localhost:8080/ でも同内容が表示された
つまりRustコードを書くだけで『デスクトップアプリ』と『ウェブアプリ』が同時に出来上がる?
もうじきTauriがモバイル対応するそうなので『モバイルアプリ』にもなるということ?
0202デフォルトの名無しさん
垢版 |
2022/03/06(日) 22:56:07.92ID:T8opxkUl
Yewはマジでelmっぽくて嫌いじゃないが、htmlの部分が一切補完効かないの結構キツい
0203デフォルトの名無しさん
垢版 |
2022/03/06(日) 23:07:04.35ID:ABwQh1O6
>>199
もちろんTauriと関係なくTauriを使わずとも
YewやWozなどのRustによるfrontend frameworkを使って
RustだけでPWAを作ってWebブラウザ上で動かすことが出来る
Tauriはそれに加えてデスクトップで動かすことが出来る
つまりWebによる制限を超えた動作も可能でデスクトップアプリとなる
0206デフォルトの名無しさん
垢版 |
2022/03/06(日) 23:16:26.97ID:T8opxkUl
>>204
Elmって状態が深くなってきたら更新するのしんどくね?
正直mutableな方が楽だと思ってるわ

>>205
うーん
0207デフォルトの名無しさん
垢版 |
2022/03/07(月) 00:40:12.93ID:2Lq6XwwP
>>194
別に大差ないと思うけどな

>>196
そのときの都合

>>197
Lispがゴミというのならそうだと思ってたけど
そうでないLispがあるなら、どれで理由は何なの?

>>198
中を見れない普通のwebフロントを書きたいか、凝ってて動作がもっさりしないように作りたいのならいいのかもしれんが、それだけのために言語的制約がきつく、誰もメンテできなくなるRustをわざわざ使う理由はないな
しかもそれをデスクトップアプリでとなるとさらに微妙
結論だけいうと、そういうのを喜ぶ人向けという非常に狭い用途
0209デフォルトの名無しさん
垢版 |
2022/03/07(月) 01:00:34.40ID:2Lq6XwwP
>>198
一言で言うともっとデスクトップアプリっぽいのを作ってほしかった
ただのweb画面ならReact Nativeでもcordovaでも使った方がメンテ出来ていいかもしれない
webはう〜んかもだけどFlutterでもいいし、Rust+Qtとかでもいい

>>208
そんなマニアックなの誰も知らねーよ。理由は何なの?
0212デフォルトの名無しさん
垢版 |
2022/03/07(月) 01:19:37.15ID:txOk/EL1
>>207
ウェブのフロントエンドかデスクトップアプリの用途でrustを使うのは微妙って言ってたのかな?
0213デフォルトの名無しさん
垢版 |
2022/03/07(月) 01:29:01.70ID:2Lq6XwwP
>>212
伝わらないなら受け取ったとおりのことを言ってくれればいいよ
せっかくRustだけで書ける環境を思いついたのに、ローカルで結局Webフロントメインのコードになっちゃったから残念な気持ちになっただけ
せっかくRustだけなのにフロント側でPWAとかもうアホの極みだろ?
0214デフォルトの名無しさん
垢版 |
2022/03/07(月) 03:52:01.06ID:2Lq6XwwP
openglベースのeguiの方がまだマシ
https://github.com/emilk/egui
ただlinux(ubuntu20.04)だとexampleすら動かない
$ cargo run --release
Finished release [optimized] target(s) in 0.09s
Running `target/release/eframe_template`
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
eframe_template: ../../src/xcb_io.c:260: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
中止 (コアダンプ)
$
まあ安全なRustだからしょうがないよね
wasmにしたら動いたけど、いろいろインストールして回る割にwasm-optがなくて躓いた(パス通してないので)
0217デフォルトの名無しさん
垢版 |
2022/03/07(月) 04:32:12.56ID:2Lq6XwwP
エコシステムが不足しすぎて不安定すぎなのに詐欺っぽい宣伝ばかり先行してて、まともな人ほど寄り付きにくい状況になってるのが問題
0218デフォルトの名無しさん
垢版 |
2022/03/07(月) 05:46:33.32ID:SxK5Ewlv
>>209
Rust frontend frameworkは10種類以上あるから好みのものを選べばよい
もちろん仮想DOMを使うReact的なものから対照的なSvelte的なものまで色々ある

>>213
むしろPWA含めたWebアプリ全般でCSRだけでなくSSR/SSGが重要との認識が一般的になった今だからこそRust利用が重要視されている
当然isomorphicにrenderingするわけだから従来はReact/Next.js Vue/Nuxt.jsといったようにサーバー側でもJavaScriptを使わざるを得えず遅くて重いことが課題となっている
そのため両サイドでRustによるframeworkを採用することで従来の課題を解決するのが最新動向
0219デフォルトの名無しさん
垢版 |
2022/03/07(月) 06:00:41.49ID:TrDR7mvG
>>218
まるで10種もあるのはメリットのように書いてるけど、デファクトがなくて労力分散されてる上にユーザーも10種吟味しないといけないのは普通にデメリットだからな
0220デフォルトの名無しさん
垢版 |
2022/03/07(月) 06:17:02.49ID:2Lq6XwwP
>>218
tauriに対する話なんでクライアント側
最終的なレンダリングをHTMLにしたいからって何が嬉しくてローカルでWebのPWA持ってくんの?
ウィジェット遠すぎてネイティブRustにする意味がないだろ

SSR/SSGのロジックをRustで書きたい話とか関係ないし、大層な結果も出ていない
Rustフロント周りのフレームで使えるモジュールはいくつか出てきているという程度で、高い品質のものが向き不向きや好みに応じて選べるような印象とはほど遠いが、いずれにせよ今回の話とは無関係
0222デフォルトの名無しさん
垢版 |
2022/03/07(月) 07:08:34.49ID:toDEeSlJ
>>213
お主フロントエンドフレームワークスレでRustを叩き棒にして荒らしてたヤベー奴じゃな?
書き込み内容やクセといい、書き込み時間といい。
0225デフォルトの名無しさん
垢版 |
2022/03/07(月) 12:29:11.51ID:2Lq6XwwP
>>224
今どきC#なんて大抵の奴が使えると思うが…
今Rustを「推して」いるやつは頭がヤバイ奴ばかりなんだな
0228デフォルトの名無しさん
垢版 |
2022/03/07(月) 13:45:18.62ID:SxK5Ewlv
>>219
JavaScriptのフレームワークは何十種類も無数にあり長い歴史の中では最近と言ってよいほど後発のフレームワークが勝ち残っているのは事実だが
そのように自由な競争があるからこそ良いものがどんどん出てくる
Rustの各分野のライブラリも同様であり利用者による健全な民主主義が機能している良きRustの方針

>>220
Tauriの話は一切していない
PWAやWebアプリと明記しているようにWebブラウザにおけるフレームワークのRustの話
CSRとSSRおよびSSGにおいて同じロジックでDOMやHTMLへレンダリングするのは事実
そしてそのコードをサーバーサイドとフロントエンドで共有しないとコード開発効率がよくないのも事実
そのため現状ではそのコードのプログラミング言語がJavaScriptとなっているがサーバーサイドで重く遅い
そこで多くの開発者たちがRustを採用したフレームワークを開発することでその解決を計っている
ブラウザ側ではWASMとなるがGCランタイムのある言語は不利なためRustが選ばれ使われている
0229デフォルトの名無しさん
垢版 |
2022/03/07(月) 22:07:29.71ID:2Lq6XwwP
健全な民主主義じゃなくて野生のまま鼻息荒い馬鹿が闊歩してグチャグチャにするだけのRust界
tauriの話しかしてないところにレスで「Tauriの話は一切していない」とかアホすぎる
Rustが件の調査で1番だったのはGCランタイムとか関係なく、安全で速いと嘯かれた人が騙されて使用してるだけ
実際には苦労して書いても速くなく、unsafeを使って初めて速くなるか、回りくどい方法を使わないと普通に書くより遅くなる
wasm自体の実体は多分ゲームが一番多いと思うので、実際はC#が強いと思う
0231デフォルトの名無しさん
垢版 |
2022/03/07(月) 22:24:36.90ID:txOk/EL1
>>229
> 実際には苦労して書いても速くなく、unsafeを使って初めて速くなるか、回りくどい方法を使わないと普通に書くより遅くなる

普通に書いたら遅くなったコード例ください
0233デフォルトの名無しさん
垢版 |
2022/03/07(月) 22:41:05.90ID:TrDR7mvG
>>228
自由なライブラリが無数にある状況を良しとするとならcommon lispも良しとしてそう
0234デフォルトの名無しさん
垢版 |
2022/03/07(月) 22:45:19.55ID:TrDR7mvG
Common Lispと同じで一部のマニアが熱狂したままで一般に浸透せずそのまま死ぬ未来が見える
0236デフォルトの名無しさん
垢版 |
2022/03/07(月) 22:54:35.35ID:TrDR7mvG
俺をキチガイアンチと一緒にするんじゃねえよ
0237デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:00:16.25ID:SxK5Ewlv
>>229
君が文脈を読めない人だから君だけが誤解している
例えば分かりやすく「PWA」という単語でこのスレを検索すると皆はTauriとは別の話をしていることがすぐ分かる
もちろんPWAの意味するところもWebブラウザ上での動作でありTauriの話とは別の話であると皆は分かっているためである

もう一つ君はRustにおけるunsafeの意味と位置づけを理解していないようだからそのような意味不明な発言となっているのだろう

>>233
ほとんどのメジャーなプログラミング言語では多数のフレームワークが競い合って良いものが残った
そうでない言語があるなら教えて欲しい
よほど特殊な例外だとわかるだろう
0238デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:01:40.70ID:TrDR7mvG
>>237
良い物以外が死ぬくらい強いのがあればいいんだよ。生き残ってきた言語はそうだった。だけど今のrustはそうはなってないのがいかん
状況はcommon lispに近い
0239デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:23:44.30ID:SxK5Ewlv
>>238
強いもの1つだけが残る死の世界を望む人はいないしそんな現実もない
例えばJavaScriptのフレームワークの最新シェアを見ても1位は31%しかなく2位が12%で3位が11%とこの3つでようやく過半数
それぞれ特徴の異なるフレームワークが多数共存していて皆がそれぞれ自分に合ったものを選ぶことができる健全な世界となっている
0240デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:30:43.91ID:2Lq6XwwP
>>231
いくらでもあるから探してみ

>>237
お前がtauriに関するレスをしたところにお前が勝手にレスしてきて「tauriの話はしていない」とか言い始めただけだろ
cordovaみたいなのはPWAもちゃんと対応してるので、PWAならtauri関係ないというのも違う
unsafeもやはりお前なのか。。。お前が分かってないだけ
0241デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:31:07.44ID:TrDR7mvG
>>239
Rustで31%とれそうな奴あるんか?
仮にあったとしてもそもそもRustのほうが圧倒的に人口少ないんやからJSの31%と同じコミュニティ規模出そうと思うと全然足らんぞ
0242デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:32:49.16ID:TrDR7mvG
ってかJSが覇権とった時ってHTML上書きとJQuery以外あったん?
0244デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:41:43.52ID:2Lq6XwwP
当時jQueryはブラウザ間の違いを吸収する役割を担ってたからというのもあるけど
0245デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:43:20.17ID:7aFZ7qh0
そもそもなんでWebフレームワークとして生き残れるかどうかって話になってるんだ?
Rustの本分はWebで言えばrustlsとかquicheみたいな最下層のライブラリ実装にあるんでは…
まぁWebフレームワークやGUIで普及するのはきついと思うよ
0247デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:50:27.38ID:wcfmwfx3
>>229
>Rustが件の調査で1番だったのはGCランタイムとか関係なく、安全で速いと嘯かれた人が騙されて使用してるだけ

デタラメすぎてあまりにも酷い
Rustを使っている人は騙されているのかw

>実際には苦労して書いても速くなく、

苦労して書くという時点でプログラミング初心者か
普通に書けば速いぞ

>unsafeを使って初めて速くなるか、

unsafeは閉じ込めた中で使うものであって普通は外でわざわざ使わん
そんなことしなくても速い

>回りくどい方法を使わないと普通に書くより遅くなる

回りくどい方法で速くなるなんて見たことも聞いたこともない
普通に素直に書けばコンパイラの最適化で十分に速い
0248デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:51:41.39ID:NArx6hWr
ID:SxK5Ewlvは出禁な
0249デフォルトの名無しさん
垢版 |
2022/03/07(月) 23:57:59.82ID:wcfmwfx3
>>245
Rustはそんな下層だけの狭い対象の言語ではない
最近はサーバーサイドで起きるWebレンダリング同一コード要請から
Webフレームワークの一定数はRustがシェアを獲得するのは間違いない
0250デフォルトの名無しさん
垢版 |
2022/03/08(火) 00:19:02.40ID:cpoDoLxs
>>249
まぁGAFAやベンチャーの採用で1-2%くらい取れる可能性は否定しないけど
現状の大半を占めるJS/Java/Rubyあたりからの移行は無理だと思うけどなぁ
0251デフォルトの名無しさん
垢版 |
2022/03/08(火) 00:23:12.80ID:2Ie6O3y5
>>247
騙されてるだけ
Rustをunsafeなしに書いたらC/C++より速くなる道理がない
制約を課している分必要メモリ量も増え、その分の時間がロスに繋がる
JIT込みで動作するVM系言語でもGC走る間もなく終わってしまう大半の簡単な処理では差などつかず、場合により簡単に抜かれてしまう

>>249
きついっつーの
JavaScriptでひぃひぃ言ってる大半のプログラマが使いにくいと思わないはずがなく、十分なメリットがないためにシェアが上がらない
全てをストリームで処理したい世界線に移動しないと無理
0253デフォルトの名無しさん
垢版 |
2022/03/08(火) 00:29:10.40ID:wlomX7u1
>>240
自分の頭が悪くて普通に書いたら遅くなるコードがどういうものなのか想像もできないので
検索キーワードだけでも良いので教えてください
0254デフォルトの名無しさん
垢版 |
2022/03/08(火) 00:38:56.95ID:2Ie6O3y5
>>252
ベンチマークは極端な仮定に基づき簡単に特性を見るもので実運用ではその通りにはならないのが通例
依存する全クレート含めてRustの外へのアクセスを除いてunsafeを全く使わないコードで動かしてみればいい

>>253
Rust
0258デフォルトの名無しさん
垢版 |
2022/03/08(火) 00:56:08.88ID:4G1DFk0q
>>257
コードを見てみましたが失格
fnの前にunsafeを付けなければなりません
かなり酷い初心者のようですが出直して勉強してからまた来てください
0261デフォルトの名無しさん
垢版 |
2022/03/08(火) 01:27:17.05ID:2Ie6O3y5
どうでもいいけど compiler explorer よく見たらvimが使えるw ちょっと感動したw
0262デフォルトの名無しさん
垢版 |
2022/03/08(火) 02:05:41.64ID:wlomX7u1
>>257
普通に書いたら遅くなるコード例が欲しかったんですがこれは何をしようとしていて何が遅くなっているんですか?
0263デフォルトの名無しさん
垢版 |
2022/03/08(火) 02:21:08.30ID:2Ie6O3y5
>>262
お前が誰かなんて知らねーし、すでに自分で探せと言ったものを何度も他人に聞くなよw 本当に頭悪いなw
0264デフォルトの名無しさん
垢版 |
2022/03/08(火) 02:27:22.25ID:ogfaAdc3
おれのコードか? 欲しけりゃくれてやるぜ… 探してみろ この世の全てをそこに置いてきた(ドン
0266デフォルトの名無しさん
垢版 |
2022/03/08(火) 02:38:10.27ID:2Ie6O3y5
レスは適当に追うけど、長すぎんだよw
複数に答えてるところで分岐があるんだし、かなり前のお前のレスを読まないと分からない内容にしてるお前の頭が悪いだけw
しかも断られた内容を「自分の頭が悪くて...どういうものなのか想像もできないので...だけでも良いので教えてください」と懇願するほどの馬鹿w
再度断られると煽りはじめ、しかもしつこく深夜まで…やばいってお前w
0267デフォルトの名無しさん
垢版 |
2022/03/08(火) 03:00:25.45ID:wlomX7u1
>>266
うんうん、わかったわかった
「普通に書いたら遅くなるコード例」はあなたからは出てこないのね
それならこれ以上やりとりしてもお互い無益なのでやめましょう
何度もレスさせてごめんね
こんな遅くまで付き合ってくれてありがとう
0268デフォルトの名無しさん
垢版 |
2022/03/08(火) 04:06:31.78ID:2Ie6O3y5
>>267
はじめに断ってんだろw 二度断ってなお煽ってきて何いってんの?w 確信犯がそれで許されるわけねーだろw
二度と書き込みませんと宣言したら許してやるw
0269デフォルトの名無しさん
垢版 |
2022/03/08(火) 04:29:07.10ID:unrSCMcN
名だたる企業がRustについての肯定的なレポートを出しているが、それも誤りだというのか?
誤りではないが、だからといってシェアがとれるわけではないというのか?
0270デフォルトの名無しさん
垢版 |
2022/03/08(火) 05:04:17.68ID:2Ie6O3y5
特定のシチュエーションで肯定的という事実だけ
それを元に何かを想像するのは自由だが、どの領域でどこまでシェアを伸ばせるかについては想像に過ぎない
さも名だたる企業が領域とシェアについて言及してるかのごとくに言い広めるのは良くない
0272デフォルトの名無しさん
垢版 |
2022/03/08(火) 06:19:02.05ID:2Ie6O3y5
自分で見つけられない人は可哀想w どこまでも煽っていくスタイルなんですねw
0273デフォルトの名無しさん
垢版 |
2022/03/08(火) 06:35:46.51ID:unrSCMcN
>>270
名だたる企業が安全だと言っている事実に誤りはないのかね?
速度もCと互角と言っているのは?
0275デフォルトの名無しさん
垢版 |
2022/03/08(火) 13:19:25.26ID:j6pRDWl/
C#ってWindows限定じゃなきゃ選択肢に上らない。いつMSがやーめた、今度はこっちにするわって言い出すかわからんもん。Rustはどうかな?
0278デフォルトの名無しさん
垢版 |
2022/03/08(火) 14:57:59.41ID:h65o/pBf
言語に関してはMSはディスコンしてもサポートがめちゃ長いから比較的安心

D言語みたいなのでもまだ続いてるからRustも今のところ心配する必要ない
衰退し始めたら気長に移行すればいい
0281デフォルトの名無しさん
垢版 |
2022/03/08(火) 22:24:39.58ID:7jRUihOa
非同期関数(非同期タスク)について質問です
単純に読むとか書くとかなどは非同期関数を呼んで待たされる(=待たせてくれる)のでawaitで待てばよいのですが
何かある仕事を専門にする人がシングルトン的に存在していてそこへ仕事を依頼して非同期に結果が出たら結果をもらう場合は
Rustではどうするのが効率がいいのでしょうか?
例えばコールバックをしてもらうとか
チャネルをもらってその読み出しで待つとか
スケジューラーの中で寝て待って起こしてもらうとか
その他など各々の可能不可能とメリットデメリットと具体的な方法が知りたいです
それに加えてタイムアウト付きで結果がまだ出ずとも時間内に戻りたい場合はどうなりますか?
0282デフォルトの名無しさん
垢版 |
2022/03/08(火) 22:42:13.35ID:FnAzWNtw
必要な機能をもった非同期ランタイムを選択する。
自分でやるなら unsafe でやることになるだろうけど本当にしんどい道のりになると思う。
0284デフォルトの名無しさん
垢版 |
2022/03/08(火) 23:20:38.55ID:4G1DFk0q
ちょっと前提が異なるけど参考情報
hyperの中核となっているService traitは非同期コールバック方式
これでサーバーもクライアントもDNS解決もコネクション張るのも全てやっている
0286デフォルトの名無しさん
垢版 |
2022/03/08(火) 23:48:42.33ID:4G1DFk0q
例えばhyperでサーバーがHTTPリクエスト受けるのにも二段のimpl Serviceが使われていて
一段目はコネクションが張られる毎
二段目はそのkeepaliveで複数回になりうるHTTPリクエスト毎

>>285
タイムアウトはその合成でいけるね
0288デフォルトの名無しさん
垢版 |
2022/03/08(火) 23:53:52.79ID:2Ie6O3y5
// こんな人向けの話
#[tokio::main]
async fn main() {
async {
println!("{}", "こんにちは世界!");
}.await;
}
0289デフォルトの名無しさん
垢版 |
2022/03/09(水) 10:50:10.12ID:E2+Mvfnk
だけど今さらJavaを選択しないだろ。終わりの始まりはOracleがSUN Microsystemsを買収したとき。
0290デフォルトの名無しさん
垢版 |
2022/03/09(水) 10:56:14.10ID:zPCTeYum
>>202
補完の効かないHTMLモドキ書くの辛ぽよな
VDOM系ならsauronがmacro以外でも書ける
個人的にはSilkenwebかな
0292デフォルトの名無しさん
垢版 |
2022/03/09(水) 12:23:18.65ID:JjWHIxM6
>>289
もちろん今となってはJavaを使う意義は全く無いが
Javaしか使えない(人材しかいない)遅れたところも存在している
0293デフォルトの名無しさん
垢版 |
2022/03/09(水) 12:49:32.47ID:o8UVaHTv
>>281
結局どこかで同期(待ち合わせ)したいならば
(1) 条件を満たしたらReadyになる自作Future<Output=T>を受け取りfuture.awaitで待つ
(2) lockされた非同期Arc<Mutex<T>>を受け取りmutex.lock().awaitで待つ
(3) 非同期channel::Receiver<T>を受け取りreceiver.recv().awaitで待つ
これらawaitの前の部分はfutureなのでタイムアウト付きにしたいなら
非同期timeout(duration, future).awaitで待つ または非同期sleepを使って
futures::future::select(future, sleep(duration))で任意の仕様で作成可
さらに多くのfutureが関係するならselect_all
0294デフォルトの名無しさん
垢版 |
2022/03/09(水) 13:01:08.14ID:sJRk7ncZ
悩ましいのが非同期処理待ち合わせにおけるタイムアウトしたときなどのキャンセル処理だな
0295デフォルトの名無しさん
垢版 |
2022/03/09(水) 13:05:17.06ID:sJRk7ncZ
unsafeに屈してtokio/mioベースでウェーイし、二度と安全などと申しません!するのが普通
これは踏み絵なのだ
0297デフォルトの名無しさん
垢版 |
2022/03/09(水) 19:04:55.67ID:o8UVaHTv
>>294
タイムアウトもしくは多数のfutureから先着一択した場合でも
残りのfutureは手元に残るしその出自も把握しているわけだから
用途ごとに必要なキャンセル処理を用意したり実施したりすればよいだけ
これは非同期でなく同期で全体の処理時間にタイムアウトを設けた場合でも起きる話
0298デフォルトの名無しさん
垢版 |
2022/03/09(水) 22:19:31.86ID:sJRk7ncZ
async/awaitなどを使わないとしても、その手の処理を実装するなら通常は非同期I/Oを使用する
もしくは同期I/Oを別スレッドから強引にclose/shutdownする
なので、非同期I/Oを使用せずに綺麗に実装するなら、常に終わるまで待つか、キャンセル自体、つまりタイムアウトを諦めるのが普通
だから非同期を使うのであれば速度優先unsafe党に入り、RustはC/C++よりちょっと遅く、C/C++同様安全でない言語です!と懺悔しながら他の言語に許しを乞う必要があるw
0299デフォルトの名無しさん
垢版 |
2022/03/09(水) 23:10:28.68ID:JjWHIxM6
>>298
プログラミングしたことないためにunsafeが何かをわかっていない人だ
わかってないからブレて毎回主張に自己矛盾
0303デフォルトの名無しさん
垢版 |
2022/03/10(木) 05:39:25.09ID:qvXllRaC
このスレ以外でも思うんだけど
言語アンチって何が目的なの?
嫌なら使わなきゃいいだけだし
他に良い言語があると思うならそれ使えばいいじゃない

特にrust使う人なんてほぼ他の言語経験者なんだし
適材適所で使う言語選んでるでしょ
わざわざこのスレに来てrust批判したり他言語マンセーしたりしたとこで
大半の人は必要なら使うし必要ないなら使わない
余りにも不毛だからそういうのやめて欲しいわ
0304デフォルトの名無しさん
垢版 |
2022/03/10(木) 05:43:47.53ID:JmzvOlHn
俺はRustの話しかしてないんだがw
君もRustを使ってunsafe党に入るのだwwww
viva! cargo-geiger!!!!!
0306デフォルトの名無しさん
垢版 |
2022/03/10(木) 07:17:23.57ID:JmzvOlHn
# ようこそ!unsafe党へ!
cargo install cargo-edit cargo-geiger
cargo new notsafe
cd notsafe
cargo add --features full tokio
cat >src/main.rs <<EOF
#[tokio::main]
async fn main() { async { println!("{}", "こんにちは世界!"); }.await; }
EOF
cargo run
cargo geiger
0307デフォルトの名無しさん
垢版 |
2022/03/10(木) 12:59:34.09ID:Kjmun471
>>306
試してないけどこれどうなるん
0308デフォルトの名無しさん
垢版 |
2022/03/10(木) 13:22:56.24ID:VpQrQVi4
geigerは依存ライブラリを含めたunsafeの使用状況を集計するツールらしい
unsafe党とか言ってる人はもしかしたら
「見えないところでunsafe使うならRustは安全アピールするな」って言いたいのかもしれないし
unsafeをカウントできることがRustの安全性のひとつであることを知らないのかもしれない
0311デフォルトの名無しさん
垢版 |
2022/03/10(木) 14:34:40.76ID:jgJuq2u4
Unsafe使うなら見えないところでやってくれ。そしてUnsafe由来のバグは出すなっていうのがRustの思想ちゃうん?
ツール使わんと見えないなら大成功では
0312デフォルトの名無しさん
垢版 |
2022/03/10(木) 15:37:06.36ID:JmzvOlHn
# 見えないところでunsafeで一旦実行できるも、ちょっと修正するとコアダンプの例w 修正はunsafeでない場所w
cargo install cargo-edit cargo-geiger
cargo new --lib maybe_safe
cd maybe_safe
cat >src/lib.rs <<EOF
pub fn read_address_4byte(address: usize) -> i32 { unsafe { *(address as *const i32) } }
EOF
cargo build
cd ..
cargo new perfectly_safe
cd perfectly_safe
cargo add --path ../maybe_safe maybe_safe
cat >src/main.rs <<EOF
#![forbid(unsafe_code)]
fn main() { maybe_safe::read_address_4byte(&0 as *const i32 as usize); }
EOF
cargo geiger
cargo run
cat >src/main.rs <<EOF
#![forbid(unsafe_code)]
fn main() { maybe_safe::read_address_4byte(0); }
EOF
cargo geiger
cargo run
0314デフォルトの名無しさん
垢版 |
2022/03/10(木) 16:15:09.98ID:VpQrQVi4
>>312
これ何でread_address_4byteにunsafeつけないで内部でunsafeブロック使ったの?
渡された数値を無条件にアドレス扱いしてそこにアクセスするのが絶対に安全だと判断した根拠を
コメントで書いといた方がいいよ
ちゃんと理由を説明できないならunsafeブロック使うのはやめたほうがいい
0315デフォルトの名無しさん
垢版 |
2022/03/10(木) 17:06:13.98ID:9EXgn135
そりゃ変なプロパガンダかまされて、こんなしょーもない言語使わされるなんてことになったら最悪だからな。
若いバカに騙されるバカ経営陣によくある話だわ。
0316デフォルトの名無しさん
垢版 |
2022/03/10(木) 17:16:27.08ID:JmzvOlHn
バグを混入させたくて混入させる人は原則いないのである。
例示は可能な限り単純化しているが、現実世界は複雑なのだ。

プログラマが「意図せず」混入させてしまうバグを「一部」言語で回避できるからこその「安全」であり、プログラマ自身が安全性を保証する側になってしまってはもはや「安全とは言えない」w
処理系が「標準」として提供するものは処理系が「安全」を保証するものと仮定して除外し、「標準以外」の安全性を確認できればプログラム全体の「安全」も仮定でき、それを機械的に可能にしているのがRustという言語w
そしてそのする「標準以外」の安全性を確認ツールがガイガー(geiger)なのだw
「標準」が「安全」と仮定される限り、ガイガーがunsafeをscanした結果☢ が1つもなければ、プログラム全体の「安全」も仮定されることになる。
もし☢があるならば、プログラム全体の「安全」は言語(処理系)でなくプログラマ自身が保証する必要がある。
この☢がある状態はC/C++と何ら変わらず、かなりのライブラリで☢が氾濫する昨今、言語が保証する「安全」についてRustに優位性は存在しない。
に依存する。

Rustコミュニティは他言語と比べれば豆粒程度なので、言語が保証する「安全」がプログラム全体の「安全」に占めるウェイトが大きくなければ、どこかで破綻し見限られ、喧伝してる手前凋落する運命となるだろうw
しかしそれでも人は速度を諦められず、unsafe党に次々ダイブしていくわけであるw

☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢
☢ガイガーカウンター=放射線測定器☢
☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢☢
0321デフォルトの名無しさん
垢版 |
2022/03/10(木) 18:05:02.01ID:jgJuq2u4
> 例示は可能な限り単純化しているが、現実世界は複雑なのだ。
それはまあその通りで、だからあんまり複雑な内容をunsafe内で書くのはやめような
0323デフォルトの名無しさん
垢版 |
2022/03/10(木) 18:17:23.72ID:rB1jhkGU
unsafe使ってるのは競プロの異常者たちだけというデータは出てるから無視で良い
0326デフォルトの名無しさん
垢版 |
2022/03/10(木) 18:33:47.69ID:2bdj2PsA
cargo install でコマンドをインストールすると依存するクレートも含めて
$HOME/.cargo/bin/registry
以下のディレクトリにソースや管理用のデータが格納されているようですが、
これらの管理というのはどのようにすればよいものなのでしょうか?

一定以上に古いものを削除するとか、
インストール済みのバイナリクレートが依存しているものだけを残すとか、
そういう機能は普通はあるだろうと思うのですが cargo のコマンドとしては見当たらず、
何か専用のコマンドを入れる必要があったりするのなら教えて欲しいです。
0327デフォルトの名無しさん
垢版 |
2022/03/10(木) 18:35:27.76ID:JmzvOlHn
単純なものの組み合わせで複雑になるのだよw
複雑になると人間的なチェックでは見落としが出るのだよw
その際にどこまで複雑になっても正確さ100%の機械的チェックは申し分なく有効なのだよw
それを(Rustの)内側だけにある要因だけで捨ててunsafe党に入ってしまうのが現状のRust w
私もあなたもunsafe! viva! unsafe! Rust is unsafe!!!
0329デフォルトの名無しさん
垢版 |
2022/03/10(木) 18:36:59.75ID:jgJuq2u4
>>327
組み合わせる前にunsafeブロック閉じよう
unsafe内で組み合わせ爆発を起こすな😡
0331デフォルトの名無しさん
垢版 |
2022/03/10(木) 18:58:28.71ID:JmzvOlHn
>>329
コンパイラチェック可能な最小限のunsafeブロックの外側が、事実上安全ではないんだよw
これをどこまで広げるかを人間が決めるのでは、複雑な現実世界に適用した際バグると言っているw
誰もがこれなら平気!バグはないというところから、バグは生まれるわけだw
unsafeがあるだけでそれは致命的な障害となるw viva! unsafe! Rust is unsafe!
0333デフォルトの名無しさん
垢版 |
2022/03/10(木) 19:22:49.02ID:JmzvOlHn
そう、つまりRustはおおよそのケースでC/C++と同じくらい安全でなく、RustはC/C++より少し遅い言語なわけだw
viva! ☢unsafe☢! Rust is ☢unsafe☢!
0334デフォルトの名無しさん
垢版 |
2022/03/10(木) 19:23:02.49ID:VmetIJtP
銀の弾丸はないんだよ
だけど物事は少しずつよくなっいくの
0335デフォルトの名無しさん
垢版 |
2022/03/10(木) 19:28:34.82ID:JmzvOlHn
そのとおり!今は嘘をつかず謙虚にユーザーが増えるのを待っていろw
非同期に必要なlibc周りのゴミゴミした部分が十二分に安定して標準に取り込まれれば逆転も可能だろw
それまではジッと我慢w
0340デフォルトの名無しさん
垢版 |
2022/03/10(木) 20:20:46.82ID:JmzvOlHn
Rustは何かにつけて長時間ビルドする上にそのサイズがクソデカイから困るんだよなw
容量足りなくていつも消して回り、ちょっと変更してフルビルドっていう繰り返しw
0341デフォルトの名無しさん
垢版 |
2022/03/10(木) 20:38:14.39ID:jgJuq2u4
>>331
ええそんなことあるか?
0343デフォルトの名無しさん
垢版 |
2022/03/10(木) 21:24:21.13ID:Bj7uYOrm
まず言語と関係なく一般的な前提として
・プログラミングをする上で当然unsafeな操作を避けることはできない
・unsafeな操作を組み合わせることで安全なプログラムを作ることがプログラミングの本質

次に
・unsafeな操作のコードは人間による厳重なチェックが必須でこれを避けることは出来ない
・unsafeな操作がプログラム全体に散らばってしまっているのがCとC++

そこでRustの方針
・unsafeな操作は局所的に閉じ込めてしまい安全なインタフェースを公開
・そのunsafeな操作で作られた安全なインタフェースの安全性は人間が保証
・データ競合を含めたプログラム全体の安全性はRustの言語ルールによりコンパイラが保証

したがってどんなにプログラムとその中のデータや依存関係が複雑化および巨大化しようとも
Rustにおいて人間は局所的に閉じ込めたunsafeな操作部分のみ厳重チェックすればよくなった

暴れている ID:JmzvOlHn はこれを理解することが出来ない愚かな存在
例えば >>312の read_address_4byte()
これはunsafeな操作を使ったunsafeな関数であるからunsafeを宣言しなければならない

>>330
ワッチョイ化しなくても愚かな存在はすぐに区別がつくので大丈夫
並行してワッチョイ無しスレも立って過疎と活性の結果となる
0344デフォルトの名無しさん
垢版 |
2022/03/10(木) 21:38:23.62ID:JmzvOlHn
>>343
> ・unsafeな操作を組み合わせることで安全なプログラムを作ることがプログラミングの本質
これ嘘w
> ・unsafeな操作は局所的に閉じ込めてしまい安全なインタフェースを公開
これ「局所的に閉じ込め」られると思ってるところがただの思いこみw
理由は
> ・そのunsafeな操作で作られた安全なインタフェースの安全性は人間が保証
これが不可能だからw
閉じ込められないと、
> ・データ競合を含めたプログラム全体の安全性はRustの言語ルールによりコンパイラが保証
これの意味がなくなるw

という説明を長々としてきたのだが、残念ながらID:Bj7uYOrmには理解が及ばなかった模様w
以上から、Rust is ☢ UNSAFE ☢! となるw

どうして理解できないんだろうなぁw
機械は言われたとおりのことしかできないけど、言われたとおりに100%ミスなくできるw
でも人間は必ずミスをするんだよw
保証できていることの意味が全然違うことを理解してほしいねw
0346デフォルトの名無しさん
垢版 |
2022/03/10(木) 21:54:57.49ID:7o5w+imS
スレの途中で作ると人移動しないかもしれない。いやでも、おじさんこんだけ激しく荒らしてるから、移動するかもしれない。
0347デフォルトの名無しさん
垢版 |
2022/03/10(木) 22:02:14.74ID:tHieothT
この手の嵐はワッチョイ導入でさぁーっと消えるw
そらもう面白いように消える不思議なことに
0350デフォルトの名無しさん
垢版 |
2022/03/10(木) 22:12:09.43ID:JmzvOlHn
どうぞどうぞご自由にw 自演なんてしてないし、別IDなんてないけどなw
そもそもまともな内容書いてないやつしかワッチョイの話してないのが非常に胡散臭いw
0351デフォルトの名無しさん
垢版 |
2022/03/10(木) 22:12:58.79ID:jgJuq2u4
>>344
そうは言ってもデバッグするときunsafeな場所が限定されている方が良くない?
0354デフォルトの名無しさん
垢版 |
2022/03/10(木) 23:13:00.51ID:jgJuq2u4
>>352
safeという強い言葉が気に入らないってこと?
それはまあちょっとわかる
0355デフォルトの名無しさん
垢版 |
2022/03/10(木) 23:16:42.15ID:Bj7uYOrm
「大規模化/複雑化すれば人間は必ずミスをする」からこそ
それを回避するためにRustが作られた

Rustコンパイラはコードがどんなに大規模化/複雑化しても
メモリ安全性やデータ競合が無いことを保証できる
その唯一対象外となるのがunsafeな操作

Rustでは局所的な極小規模で単純な部分にunsafeな操作を閉じこめる
そして外へは安全なインタフェースのみを公開
人間にしか出来ないunsafeな操作利用の妥当性チェックを最小化することに成功した
どんなに大規模and/or複雑化してもプログラム全体の安全性を人間がチェックする必要が無くなった

一方でCやC++などはプログラム全体にunsafeな操作が散らばり人間の手に負えない
GC導入のハンデと引き換えにメモリ安全性の一部を得たGC言語であっても
ヌルポインタを含む一部のメモリ安全性やデータ競合などを防ぐことが出来ていない
それらの安全性を保証することに成功したプログラミング言語がRust
0356デフォルトの名無しさん
垢版 |
2022/03/10(木) 23:32:10.55ID:JmzvOlHn
可哀想なくらいに他人の言葉を受け入れられない人だねw
Rust作られた目的まで捏造されちゃったよw
unsafeを閉じ込められるというのは幻想w
外には安全なインターフェースのみ公開という理屈が「仮定」できるのは処理系とのそこが提供する標準含むランタイムだけw
プログラマが実装するプログラムはunsafeを使った途端にプログラム全体がもうunsafeでC/C++と同じなんだよw
GCは関係ないw
リアルタイム性を予測可能にするためにランタイムが予測不可能な時間を使用することを回避したい場合のみGC有無が関係するw
null安全は書き方だけであり、他の言語でも大抵似たようなことが実現できるし、機械的なチェックも可能w
そしてC/C++と同様に安全性が保証できず、C/C++より遅い言語が何を隠そうRustさんw
0357デフォルトの名無しさん
垢版 |
2022/03/10(木) 23:34:44.83ID:JmzvOlHn
>>354
viva!tokio!な現状だと安全ではないと言ってるだけw
cargo geigerで☢がなければ(C/C++より)安全って言ってもいいと思う
0359デフォルトの名無しさん
垢版 |
2022/03/10(木) 23:58:49.51ID:Bj7uYOrm
>>356
ほら、理解できていない
unsafeで作られた安全なコードに対する人間による妥当性チェックの必要性は
それが標準であろうとデファクトであろうと自作であろうと全て同じ

逆に言えばその局所的なコードの妥当性チェックがなされていれば
Rustではプログラム全体の妥当性がコンパイル時点で保証される
Rust以外のプログラミング言語はこれができない
0360デフォルトの名無しさん
垢版 |
2022/03/11(金) 00:07:06.62ID:GmBPyzdt
>>359
理解できてないのはお前w
ランタイムやVMは他の言語でも別枠だからプログラム本体とは切り離して安全としていいんだよw
そこは言語が規定してる部分だからだw
C#やJavaでVMがnativeだからって文句言うアホはいないし、各種インタプリタ言語の組み込み関数が何で書かれてても誰も何も言わないだろw
RustよりはC#やJavaの方が明確に安全と言えるけどなw
Rustだと言語の内側からunsafeにしたいという欲求が生まれる温床があり、不必要にunsafeが発生しうるw
0361デフォルトの名無しさん
垢版 |
2022/03/11(金) 00:49:50.34ID:KdADcOUe
もし仮にTokioが標準ライブラリならOKなのか?
標準ライブラリにバグがある確率とコンパイラにバグがある確率は同じくらいとして
0362デフォルトの名無しさん
垢版 |
2022/03/11(金) 01:19:06.80ID:yxfxX1kD
標準ライブラリはもの凄い小さくて、あとは個人や小さな組織が作った野良ライブラリだよりだから、
安全性は全然担保されてないと思うがなぁ。
0363デフォルトの名無しさん
垢版 |
2022/03/11(金) 01:40:55.24ID:R2y3WlG0
どの言語であれ
標準ライブラリやランタイムに問題が生じなかった言語は存在しない
だから『標準』と名が付くかどうかはどうでもよい問題

Rustにはunsafeか否かの区別があるから他の言語より遥かに良い状況
標準か否かに関係なくunsafeではないコードに対してunsafeを冠せずに出したら厳しく指摘される
そしてunsafe以外についてはコンパイラが通れば安全性が保証される
0364デフォルトの名無しさん
垢版 |
2022/03/11(金) 02:00:44.40ID:uv7nfwNg
でかい標準ライブラリを許容してると、言語をメンテしてる人たちにとっては切り捨てもできず、互換性を担保するのとかでどんどん負担もでかくなるし、言語自体の進歩まで遅くなりうるよ
Goの進歩がやたら遅いのも、もしかしたらそういうとこにも原因あるかもね
0365デフォルトの名無しさん
垢版 |
2022/03/11(金) 03:37:56.52ID:KdADcOUe
しかし非標準で同じようなライブラリが乱立してるような状況では新規言語に飛びつきたい言語オタクの精神異常者以外には参入し辛い状況ではある
普通の人普通の企業にとってはGoの方が魅力的に映るだろうな
進歩が遅いのも一度勉強した知識がそのまま使い続けられるし一度書いたコードが使い続けられるってことだし
0366デフォルトの名無しさん
垢版 |
2022/03/11(金) 04:08:28.95ID:R2y3WlG0
>>365
逆でしょ
RustはGoogle含めた大手IT企業から全面支持
そしてRustは後方互換性も維持しているから2018editionと2021でもほとんど変わらない
安心して導入できる

そして一番重要な言語機能
Goは今年ようやくジェネリクスだけど期待外れ
イテレータ導入提案すら何度も却下
GoとRustどちらも書ける人なら確実にRustを選ぶ現実
0367デフォルトの名無しさん
垢版 |
2022/03/11(金) 04:20:44.43ID:KdADcOUe
>>366
Googleなんて言語オタクの精神異常者集めた企業の代表じゃん。そりゃそうなるよ。Common Lispとか好きそう

ジェネリクスとかイテレーターがなくてガッカリしてるのも言語オタクの特徴だな。普通の人はそれでいいって思ってるよ
0368デフォルトの名無しさん
垢版 |
2022/03/11(金) 05:51:22.53ID:egx2H9Pr
ほんとこのおじさん言語叩けりゃ何でも良いんだな。今度の棒はGoか。んでまだCommonLispのこと根に持ってる。そしてホントは.NET好きなのは隠しきれてない
0369デフォルトの名無しさん
垢版 |
2022/03/11(金) 06:14:29.85ID:GmBPyzdt
標準ライブラリならOKだよ
入っていると入っていないでは雲泥の差がある
処理系が責任を持って開発する部分で、基本部分である以上、ユーザーが少なくてもunsafeでも最大限の品質が保証されるから
言語仕様開発や処理系側からすれば、そんなところを大きくすると言語自体が保証する安全性にケチがつきかねないから小さくしたい心情はあると思う
純粋にフットプリントは小さくしたいしね
ただスレッドや同期機構まで用意してるので、世の流れとして非同期くらいまでは標準にしないと扱いにくいとは思う
切り離しやすく決まってると嬉しい
他の言語との比較はRust自体の説明に必要でない限りこのスレではしない
0370デフォルトの名無しさん
垢版 |
2022/03/11(金) 09:41:54.29ID:AW3C8472
なんだ、コード見て技術的なこと話してたらな、て思って見に来たら、
他のスレと同じで言語があーだこーだ言ってるだけか
まあ5chはこんなもんか
0371デフォルトの名無しさん
垢版 |
2022/03/11(金) 09:58:37.49ID:rj0Vocfx
unsafeがあるからダメなんじゃない
unsefeじゃないところがsafeなのがRustの大発明
0372デフォルトの名無しさん
垢版 |
2022/03/11(金) 11:23:22.26ID:H8qFXNfY
曖昧な感想をダラダラ書くより、これを紹介したほうが有意義だろ。

安全と危険のご紹介
ttps://doc.rust-jp.rs/rust-nomicon-ja/meet-safe-and-unsafe.html
0373デフォルトの名無しさん
垢版 |
2022/03/11(金) 11:54:34.16ID:GmBPyzdt
とりあえず英語版の方が内容新しいんで、こちらへ
https://doc.rust-lang.org/nomicon/working-with-unsafe.html

このexampleの2番目の
if idx <= arr.len() {
なんかが典型的で、これ気付けません。直後にあるとおり、

”...This program is now unsound, Safe Rust can cause Undefined Behavior, and yet we only modified safe code. This is the fundamental problem of safety: it's non-local. The soundness of our unsafe operations necessarily depends on the state established by otherwise "safe" operations...."

なわけ。
テキストでは最終的に可視性を利用して局所化してみたいなハウツーを入れてるけど、それは対策方法であって、局所化できる保証はない。
人間にミスは必ずあるからね。
どう書けば安全か分かっていて、それを確実に守れるなら、人間はC/C++でもバグ1つなく完璧にコーディング出来るはずなんだよ。

ってわけで、Rust is ☢UNSAFE☢ !!!!
0374デフォルトの名無しさん
垢版 |
2022/03/11(金) 12:12:51.12ID:YhXLzsgi
>>373
紹介している内容と主張している内容が一致していないように思えますが
unsafeが一つでもあればunsafeだと主張してるのかな?
0375デフォルトの名無しさん
垢版 |
2022/03/11(金) 12:18:09.85ID:H8qFXNfY
>>374
unsafeに閉じ込めるのはプログラマの責任、ということだろ。

Rustがunsafe以外で未定義動作にならないことを保証しているんだっけ?
0376デフォルトの名無しさん
垢版 |
2022/03/11(金) 12:25:34.38ID:egx2H9Pr
Haskellに対してモナドで副作用してるから純粋関数型言語じゃねえって感じの主張してはるんやろ
0377デフォルトの名無しさん
垢版 |
2022/03/11(金) 14:14:05.70ID:bW78VsKw
モナドが副作用起こしてるんじゃなくて実装系が副作用起こしてるんだけどね。
まああの辺の無駄な解釈学振り回すことばっかりな点は同じクソさを感じるわな。
0379デフォルトの名無しさん
垢版 |
2022/03/11(金) 16:22:44.16ID:Agk6xs7V
言語の理屈の立て方とそれの実現の仕方はレイヤが違う話だし、
言語の話をする以上は言語の理屈を軸にするしかしょうがないじゃん。
0380デフォルトの名無しさん
垢版 |
2022/03/11(金) 21:29:04.10ID:o63L8Mvt
>>373
unsafeを用いて安全なコードを書いている部分に対してのみ
人間が注力することができるようになったRustは他の言語より進んでると理解できた?

>>375
unsafe以外ではRustは未定義動作(undefined behavior)がないことを保証

>>379
そこは理屈というか理論というか抽象的な概念で理解しておくべきところだね
実装や内部表現は変わりうるし最適化で消滅しうるので実現方法で理解しようとしても不安定で無意味
0381デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:04:07.65ID:GmBPyzdt
>>380
何度言っても「unsafeを用いて安全なコードを書いている部分」が人間には限定できないのを理解できてないのはお前w
0382デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:23:27.18ID:/JvA5shV
>>367
Goが魅力的と書いておいてGoogleをそこまで叩くちぐはぐさ
Rustを叩ければ棍棒は何でもいいんだな

>>381
まだ意味不明なこと言ってRust叩きしてるのか
敗北を認められなくて引くに引けずかね
0383デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:25:07.91ID:KdADcOUe
>>382
叩く・叩かないや敵味方のような二つでしか考えられないのか?
0384デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:29:38.47ID:GmBPyzdt
>>382
論理的に反論されたことがないという認識なんだがw
上から頭ごなしにこうです!と言われて、いやこうこうこういう理由でそうとは思えないと伝えたら、
「意味不明」とか「Rust叩き」とか、「敗北を認められな」いと言われて議論が終わっちゃうだけw
0385デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:30:30.36ID:/JvA5shV
>>383
自分が何を書き込みしたのか見直そうぜ

>>365
>>普通の人普通の企業にとってはGoの方が魅力的に映るだろうな

>>367
>>Googleなんて言語オタクの精神異常者集めた企業の代表じゃん
0387デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:33:05.04ID:KdADcOUe
>>385
両方ともただの事実だが
0388デフォルトの名無しさん
垢版 |
2022/03/11(金) 23:37:39.97ID:/JvA5shV
>>384
Rustの言語ルール及びunsafeとそれ以外(safe)を分けることで
初めてコンパイラが通れば安全性を保証すること成功した枠組みを
未だに理解できずイチャモンつけるだけしか出来なくて恥ずかしくないのかね?
0389デフォルトの名無しさん
垢版 |
2022/03/12(土) 00:00:00.86ID:aEfI8PjB
>>388
別にunsafe自体はRustが作ったわけじゃないよw
C#が大昔にunmagedなコードを呼び出すために開発した
Rust同様に別にどこまでも範囲は広げられる
Javaもnativeってあるよね

この2つは基本的にVMが保証している枠組みを外れる部分に対して使用されてるので、VM内のコードが実行される限り、使う動機が発生しない
対してRustは安全を担保するための所有権の仕組みを逃れるためなど、unsafeを使用する動機がいたるところにある
標準が提供しているライブラリが足りないこともあり、これは相当深刻な状況なわけだw

すると、両者が意味するunsafeな部分の意味が大きく変わってくる。
簡単に言えば原則safeな部分を書き換えるためにunsafeが使用されないかどうかの違いw
残念ながらRustは安全を担保するための所有権の仕組みを逃れるためなどの理由でsafeな部分を書き換えるためにunsafeが使用されてしまっている
Rustがunsafeな理由の1つはこの動機の部分に潜在的な問題があるってことw
0390デフォルトの名無しさん
垢版 |
2022/03/12(土) 00:07:08.44ID:H1575t4R
unsafeの話はマジで意味不明なイチャモンでしかないな
25860の方がよっぽどやべえだろっていう
0391デフォルトの名無しさん
垢版 |
2022/03/12(土) 00:10:33.34ID:MeH0OP6r
>>389
Rustはデータ競合やメモリの安全性を保証する
しかしJavaもC#も保証することはできず無関係
Rustよりも優れたプログラミング言語を持ってこないとこの件でRustを批判するのは無理
0393デフォルトの名無しさん
垢版 |
2022/03/12(土) 00:40:06.84ID:aEfI8PjB
unsafeはなければ未定義動作が発生しないと仮定できるw
RustだけでなくVMで動いてるものは当然メモリ安全だって仮定できるw
Rustの場合は特性としてnativeであり所有権に制限を付けることで、パフォーマンスへの影響が少ない形で安全を仮定でき、さらにデータ競合がないことも仮定できるのが有利なところw
ただ、unsafeがあるだけでそこは無制限に全て瓦解してしまうんだよねw
そして付けた制限に対する回避のためにunsafeを使用するという潜在的な問題があり、さらに標準の機能不足により、unsafe増加が加速し、収拾がつかない大☢UNSAFE☢時代に突入しているわけだw
Rust is ☢UNSAFE☢! おーまいが!
0394デフォルトの名無しさん
垢版 |
2022/03/12(土) 00:42:18.98ID:aEfI8PjB
Rustが安全だというなら、cargo geigerで☢がない状態にしてから言ってくださいねw
0395デフォルトの名無しさん
垢版 |
2022/03/12(土) 04:41:10.84ID:VHcg50GX
cargo geigerの存在がRustがベターであることを証明してて笑える
0396デフォルトの名無しさん
垢版 |
2022/03/12(土) 05:34:45.69ID:aEfI8PjB
そういうのは他の言語なら機能性だけで分かるし、nativeならnativeで閉じてるから安心できるんですよね
でも何度も言うようにRustは何をしなくとも自らunsafeを入れてしまうので調べないと分からないw
しかも使い方的にその場所だけに閉じないため、☢UNSAFE☢を実感できてしまうとw
0401デフォルトの名無しさん
垢版 |
2022/03/12(土) 07:37:25.45ID:aEfI8PjB
どのレスを指してるのか知らんが、俺を指して言ってるなら人違いw
ってか煽ってるだけで何もできなそうな奴多すぎw
芸風とかどうでもいいし、それを気にするならお前の芸風がキモいだけw
0402デフォルトの名無しさん
垢版 |
2022/03/12(土) 07:38:35.78ID:N7+EgIAn
人を煽るくせに自分が煽られるとすぐ被害者面するの、かまってちゃんおじさんの平常運転です
0403デフォルトの名無しさん
垢版 |
2022/03/12(土) 07:45:19.39ID:aEfI8PjB
ID変えて大変だねw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0405デフォルトの名無しさん
垢版 |
2022/03/12(土) 08:10:52.33ID:aEfI8PjB
流そうとして必死なのはお前w 俺はもう飽きてるぞw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0408デフォルトの名無しさん
垢版 |
2022/03/12(土) 08:14:09.67ID:aEfI8PjB
飽きすぎたわw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0409デフォルトの名無しさん
垢版 |
2022/03/12(土) 08:23:02.74ID:4DPn029u
荒らしにとって一番辛いのは叩かれることじゃなくて無視されること
NGにすればいいけど、もっといいのは違うかまってちゃんを全員が構うようになるとそうとう辛いw
0410デフォルトの名無しさん
垢版 |
2022/03/12(土) 08:24:36.31ID:aEfI8PjB
荒らしじゃないんだよなぁ・・・俺だけだよ。本当にRustの話してるのw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0413デフォルトの名無しさん
垢版 |
2022/03/12(土) 08:44:33.37ID:aEfI8PjB
もう20レスくらい俺以外Rustのラの字もないなw

ワッチョイ入れてもねぇw NGとかなかなかしないんよねw しかも俺結構大手のプロバイダだから多分被るよw
俺には関係ないからどうでもいいけどw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0415デフォルトの名無しさん
垢版 |
2022/03/12(土) 09:02:02.69ID:aEfI8PjB
ワッチョイなんて俺には何の関係もないんだがw
俺が言うのもなんなんだが、Rustに関係のない話はやめた方がええでw
現状Rustというゴミ言語は俺にすら有効性を認めさせられないってことで、世間に広まるのは夢のまた夢なんだよなぁ・・・

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0416デフォルトの名無しさん
垢版 |
2022/03/12(土) 10:04:24.24ID:ThmhmMsv
Rustが一部の高齢(脳年齢)エンジニアを狂わせるunsafeな言語であることが示されつつあるな
Rustがunsafeなのか高齢エンジニアがunsafeなのかは意見が分かれそうだが導入するときは要注意かもしれない
0417デフォルトの名無しさん
垢版 |
2022/03/12(土) 10:13:42.44ID:aEfI8PjB
裏ではtokio使って、非同期でも何でも簡単に使えます!安全です!とか他スレでホラ吹きまくってるからだろw
嘘をついてまで他スレに喧伝までしてなければ誰も叩いたりはしない

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0418デフォルトの名無しさん
垢版 |
2022/03/12(土) 11:04:21.69ID:JxEFMwOe
実際はRust以外がunsafeで、Rustは一部safeなところがあるだけだけどね
高齢者はみんなcでunsafeに慣れてるから、Rust使わんでもunsafeだよ
0420デフォルトの名無しさん
垢版 |
2022/03/12(土) 12:04:42.93ID:aEfI8PjB
Rust以外がunsafeは嘘w C/C++などの古い言語は全部unsafe w
ただRustもunsafeな領域を人間には確実に限定できないので、☢があれば実質全部unsafe w

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0421デフォルトの名無しさん
垢版 |
2022/03/12(土) 12:18:34.97ID:ARhhT+a7
>>420
無知すぎるな
geigerは標準ライブラリを調べていない
そしてRustの標準ライブラリの中はもちろんunsafeだらけ
それなのにgeigerは一番肝心な標準ライブラリを調べていない

それはなぜか?
unsafeの正しい使用には全く問題がないからだ
unsafeを使ってそれを内部に閉じ込めて外部に安全なインタフェースのみ提供する
標準ライブラリを含めてライブラリはこの安全なインタフェースを提供している
0422デフォルトの名無しさん
垢版 |
2022/03/12(土) 12:37:50.92ID:aEfI8PjB
>>421
> geigerは標準ライブラリを調べていない
そんなことは>>316で書いたw
>>356 >>369でも言ってるとおり、ランタイム/VM+標準ライブラリは「前提として」100%信用するw
この境界は区別しないとプログラム全体の安全性が定義できないし、それらの実装言語は何でもアリだからw
0423デフォルトの名無しさん
垢版 |
2022/03/12(土) 12:45:28.26ID:8rIifBup
rustは "安全な言語" じゃなくて "比較的安全なシステムプログラミング言語" だよ
議論のポイントがずれている
0424デフォルトの名無しさん
垢版 |
2022/03/12(土) 12:50:29.49ID:VHcg50GX
unsafeを混在させたくないなら自分で書けばいいだけだよ
その選択ができることが他所とは違うところ
0425デフォルトの名無しさん
垢版 |
2022/03/12(土) 12:53:38.99ID:ARhhT+a7
>>422
愚かだな
どのプログラミング言語においても標準ライブラリに問題が発見されて修整されてが繰り返されてきた
標準ライブラリとなっけられているからといって100%信用できるわけがない
そこには何も保証がない

一方でRustならば標準か否かに関係なく保証ができる
unsafeを利用して安全なインタフェースを作った部分のみ人間がチェックすればライブラリ全体の安全性はRustの言語が保証できる
Rust以外の言語はライブラリ全体を人間がチェックしなければならない
Rustがこの点で全ての言語に対して優れていることは誰の目にも明らかだ
0426デフォルトの名無しさん
垢版 |
2022/03/12(土) 13:01:02.47ID:6Ov0/1Y8
で、おまえその優れた言語で何か書いてんの?え?actixのサーバー?コマンドラインのプログラム?(笑)
0427デフォルトの名無しさん
垢版 |
2022/03/12(土) 13:08:00.19ID:aEfI8PjB
>>423
ずらしてるんだけどねw

>>424
残念ながら世の中の需要はそうなっていないから、>>335と言ってたわけだよw
分離できる言語は多いけどw

>>425
そこを保証するのは処理系側なんて、その言語の利用者側は100%信用するしかないんだよw
標準以外がunsafeを利用してたらもう終了w なんで理解できないのかなw

>>426
匿名掲示板でそういうのは聞かないだろ普通w お前が言ったらじっくりいろいろ聞いてやるよ(俺は言わないw)
0428デフォルトの名無しさん
垢版 |
2022/03/12(土) 13:10:43.13ID:4DPn029u
>>426
主要基本orミドルの書き換え
今はLi*uxというあるOSを全てRustで書き直すプロジェクトの統括責任者兼主席ブログラマやってます
0429デフォルトの名無しさん
垢版 |
2022/03/12(土) 13:17:12.35ID:VHcg50GX
他所とは違う点は認めるのね
0430デフォルトの名無しさん
垢版 |
2022/03/12(土) 13:22:49.30ID:aEfI8PjB
>>429
そっちは読んでもいねーよw 俺宛て以外読みたくないだろ面倒だからw
まあ返事はしなくても分かると思うけどw
0435デフォルトの名無しさん
垢版 |
2022/03/12(土) 14:42:01.36ID:ARhhT+a7
>>434
その>>312を見たが作った関数がunsafeなのにunsafe宣言をしていない
ルールを守らずにunsafeを使用してはいけない
ルールもわからない初心者ならばunsafeを使うな
0438デフォルトの名無しさん
垢版 |
2022/03/12(土) 14:53:48.90ID:aEfI8PjB
#![forbid(unsafe_code)]
fn main() { maybe_safe::read_address_4byte(0); }

(unsafeじゃないから)ヨシッ
    ∧  /ヽ
   // ̄ ̄\|
   ∠_╋__〉
  / @八@ ヽ _
  工ニf(_人_)エ二|′)ヽ
  \ヽヽノノ ノ ヘ |
⊂⌒)_>―――′イ (_)
 `ー、_ノ/ ̄ヽ |
   _||  | |
  (  人_ノ Λ
   \ス ̄ ̄レ-Λ \
  ( ̄ ) / / \ノ\
    ̄ ̄ ( ヽ  \_)
      \ノ
※全文は>>312参照
0439デフォルトの名無しさん
垢版 |
2022/03/12(土) 14:59:12.25ID:VHcg50GX
だから、比較的安全、ということでいいでしょ
オフィシャルも含めてそれはみな承知のことだよ
0440デフォルトの名無しさん
垢版 |
2022/03/12(土) 15:04:06.13ID:aEfI8PjB
比較的安全という「希望的推測ができる」だけで、実際にはC/C++と全く変わらないw
前にも言ったけど、ミニマムなunsafe領域を含む「設計意図としてのunsafe」が示せるだけw
0441デフォルトの名無しさん
垢版 |
2022/03/12(土) 15:17:24.76ID:VHcg50GX
全く変わらないというのは、同じものを同じ人がCとRustで書いたとき、問題が起きる確率は変わらないだろうということ?
0442デフォルトの名無しさん
垢版 |
2022/03/12(土) 15:24:02.56ID:ARhhT+a7
>>440
違いを理解しよう

C/C++では安全性の保証は無し
ライブラリ含めて全てのプログラムに対して相互に関係する影響について人間が全てチェックしなければならない

Rustでは言語がすなわちコンパイラが安全性の保証をすることができる
unsafeを使った部分のみその影響範囲が閉じていることを人間がチェックするだけでよい
0443デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:06:48.08ID:aEfI8PjB
作り方の問題で言語の理解がしっかりしてればどちらも同じように出来るw
機械的な保証があるかないかが問題で、その分はunsafeがある時点で保証できなくなるだけw
ただし、Rustには作り方に制限があるため、その作法でC/C++が実装された場合の話にはなる、というだけの話w
C/C++で作法を守らない部分の責任は人間側で負う必要があるw
C/C++とRustどちらも保証はできないw
0444デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:09:18.50ID:gqCw8ds0
Unsafe使ってたらSafeじゃない理論ってC#でもFFI使ってたらUnsafeってことでいいの?
0445デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:28:56.66ID:aEfI8PjB
C#はunmanagedなコード以外でunsafeを使用する動機がないので懸念点がない上に、外部の何かへのアクセスが前提で、managedなオブジェクトの書き換えはあまり発生しない。
例外的にmanagedなオブジェクトを書き換える場合でも、unmanagedコードがロジック自体を持たないのが普通。
他方Rustは所有権の制限を適用しない目的などでオブジェクトを書き換えるため、それ自体がロジックの一部となっている。
例えば他のライブラリやシステムコールを利用してるなど、明確に分かるものがあればまだいいが、そういうのがないただのデータ構造に対するロジックなどにもunsafeが適用されるため、利用者側からは想定すらできず、それらを発見するためのツールが必要になってる状況も踏まえ、事態は深刻である。
そして多すぎるunsafeのせいで、それらを利用者側が正確に分類・把握できない、もしくは気付いてすらいないのが現状w
実験室向けの簡単なコードならそれでよくとも、製品レベルのコードでそれは致命的であるため、安易な「安全宣言」は悲劇しか生まないw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0446デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:29:32.03ID:ThmhmMsv
C#はFFI使わなくてもぬるぽ(ぬるり?)できるから最初からunsafeかと
せぐふぉじゃなければセーフというなら話は別だけど

Rustはunsafeな範囲を可視化できてその範囲指定が正しいことを機械的に保証できるから
C/C++に比べて比較的安全(安全性を担保しやすい)って話なんだけど
0か100でしか考えない人間にはこの差が見えないのかもしれないな
0447デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:33:40.22ID:aEfI8PjB
「Rustはunsafeな範囲を可視化できてその範囲指定が正しいことを機械的に保証でき」ないのですよw
機械的に保証できるのは俺の言い方だとミニマムな部分だけw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0448デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:39:30.29ID:VHcg50GX
変な言い回しするから言いたいことがよく分からない
自分でunsafe書いてなくても、依存関係がunsafeを濫用してたらアプリケーション全体としてはunsafeじゃないか
という主張なんだよねたぶん
0449デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:51:59.88ID:aEfI8PjB
俺の主張の大事な点は2つだよ
・安全とするにはunsafeと宣言すべき関数を機械的に決めることが出来ない
・安全のために所有権に厳しい制約を課しているが、その厳しさからunsafeを使う動機が常に言語内にある

これらから導かれる推測は多岐にわたるけど、分かりやすい結論として
Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
という警鐘を鳴らしているだけw
0450デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:57:57.83ID:VHcg50GX
一つ目言ってる意味がもう分からないんだけど
普通に言ってくれ
0451デフォルトの名無しさん
垢版 |
2022/03/12(土) 16:59:02.17ID:VHcg50GX
わっチョイの議論が出てるけど個人的には過疎るから賛成できない
この人は語尾wでNGすればいいだけと思う
0453デフォルトの名無しさん
垢版 |
2022/03/12(土) 17:10:56.57ID:cQ3TFkgX
安全のために所有権に厳しい制約を課しているが、その厳しさからunsafeを使う動機が常に言語内にある

わからんでもないかもしれん
0454デフォルトの名無しさん
垢版 |
2022/03/12(土) 17:38:29.48ID:olrB42jq
>・安全とするにはunsafeと宣言すべき関数を機械的に決めることが出来ない

安全とするには〜する必要がある
なら分かるが、

安全とするには〜出来ない
なので主張がわからんという話でしょ
0455デフォルトの名無しさん
垢版 |
2022/03/12(土) 17:44:06.44ID:ARhhT+a7
>>448
『自分でunsafe書いてなくても、依存関係がunsafeを濫用してたらアプリケーション全体としてはunsafeじゃないか
という主張』は
実際に使われているモジュールでそういう例があるならば成り立つ
しかし現実にはunsafeなモジュールは存在しなくて
>>445はその例を挙げることすら出来ていない
机上の空論を繰り返しているのみ
0456デフォルトの名無しさん
垢版 |
2022/03/12(土) 17:47:55.25ID:ARhhT+a7
>>453
その場合ですらunsafeは使っても構わない
そのunsafeを使った局所的な部分に影響が閉じ込められていて安全なインタフェースのみ公開されていればよい
そしてRustコンパイラは残り全体の安全性を保証できる
0458デフォルトの名無しさん
垢版 |
2022/03/12(土) 18:22:27.94ID:aEfI8PjB
>>454
(安全とするにはunsafeと宣言すべき関数)を機械的に決めることが出来ない
こう書けば分かるのだろうかwwww

>>455
issueがないとでも思ってるの?wwww

>>456
「そのunsafeを使った局所的な部分に影響が閉じ込められてい」る前提がおかしいw
安全なインタフェースとは誰が判断するの?wwww
どうなってたら安全なの?wwww
それを人間が判断する以上、どこまでも間違いは起きるよw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0459デフォルトの名無しさん
垢版 |
2022/03/12(土) 18:34:51.66ID:w6D1v3Ro
反応してるやつも同レベルの荒らしだから、いっしょくたにあぼーんしましょうね
0461デフォルトの名無しさん
垢版 |
2022/03/12(土) 21:08:03.28ID:gqCw8ds0
例えばTokioを使ってUnsafe由来の変な落ち方する例とかが有ればUnsafe使ったライブラリ全然信頼できねーなって同意すると思う
0464デフォルトの名無しさん
垢版 |
2022/03/13(日) 16:13:24.15ID:VLrvk/Ce
次スレはワッチョイつけますから覚悟しておいてください
それまでの命だ
せいぜい楽しむがいい
0465デフォルトの名無しさん
垢版 |
2022/03/13(日) 16:28:13.28ID:ZgBuX4v3
>>463
読んでみました
・質問者がunsafeの言葉を使い間違えてました
・ランタイムを何度も複数回スタートさせていました (そしてunsafeな状況は起きていない)
などで
(unsafeを使って)安全でないインタフェースを公開してしまったわけではないようです

>>464
反対です
過疎ってRustが不利になるだけなので
皆がワッチョイ無しスレも立てる結果となるでしょう
0467デフォルトの名無しさん
垢版 |
2022/03/13(日) 17:06:55.70ID:fVzSesSr
スレの終わりに切り替えて結構すんなりワッチョイスレに移行できたスレ多いよ。途中でもうまくいくかはよくわからん。
何れにせよ、スレが機能してないよりは過疎のほうがマシだな
0468デフォルトの名無しさん
垢版 |
2022/03/13(日) 17:17:53.93ID:SbmrJ+bY
変化が多い言語でデファクトも定まってないし、ワッチョイ付けてもたぶん過疎らないと思うけどな
0469デフォルトの名無しさん
垢版 |
2022/03/13(日) 17:27:03.14ID:vwVaodxg
そもそもみんなまともにrustの話をしたいのに
おじさんが関係ない自演で横から茶々入れるから
みんなめんどくさくなっていなくなるのよ
その自覚はある?
0470デフォルトの名無しさん
垢版 |
2022/03/13(日) 17:37:09.51ID:5bV//KSp
ワッチョイスレはもうあるぞ
ここからさらにワッチョイスレ作っても分岐して打ち捨てられたワッチョイスレが増えていくだから先にこっち消費してくれ

https://mevius.5ch.net/test/read.cgi/tech/1532697692/
0471デフォルトの名無しさん
垢版 |
2022/03/13(日) 17:47:33.76ID:e39Fa4ck
>>465
質問者?issueで質問者って何の話してんだよw
全部読んで少なくともその中にないことを証明するんだぞw
どこを読んでそう書いてあったのかすらないのでは、証明にはならないw
約 567,000 件あるけどなw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0472デフォルトの名無しさん
垢版 |
2022/03/13(日) 17:50:57.99ID:spUFJg1H
今回のやつはずっと同じIDの上に
文面から即NGできるにもかかわらずしつこく構ったやつらが悪い

反省しろ
0473デフォルトの名無しさん
垢版 |
2022/03/13(日) 18:17:55.15ID:vwVaodxg
かつて自治厨と言われた俺の手腕を発揮してやるよ
最近はそこまでの情熱は無くなったが去年あたりからrust始めたからまともに議論したいのよ
0474デフォルトの名無しさん
垢版 |
2022/03/13(日) 18:37:10.97ID:YWz/r5zq
荒らされるよりは過疎るほうがマシ
ワッチョイひとつでこの手合はピターッと来なくなるから
0475デフォルトの名無しさん
垢版 |
2022/03/13(日) 18:40:27.18ID:ZJiz2Azs
そう思うならさっさとワッチョイスレ立てればいいじゃん
なんでやらないの?
0476デフォルトの名無しさん
垢版 |
2022/03/13(日) 18:42:49.11ID:8lssQzCw
ワッチョイ有りRustスレは既に>>470にあるので使い分ければよい
ここはワッチョイ無しRustスレなので次スレもワッチョイ無しで行く
両方あれば全員に不満はない
0477デフォルトの名無しさん
垢版 |
2022/03/13(日) 18:50:17.44ID:jvwFmcnZ
使ってないスレを再使用するのはスレを無駄にしないという点では有意なんだけど、勢いもスレ順も変だから人はあんまり来ないのよね。で、何も知らずに来た人が荒らしにかまってしまう。
何れにせよ15がワッチョイ無しというのはありえない選択肢。
0478デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:25:23.33ID:8lssQzCw
>>477
ここはワッチョイ無しRustスレの系統
だからここの次スレはワッチョイ無しで確定している

ワッチョイ有りRustスレは立てられても放置されるという歴史がある
再び放置スレを増やすようなことをしてはいけない
以下に現存するワッチョイ有りRustスレがある

プログラミング言語 Rust 4【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1514107621/

Rust part6【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1532697692/
0479デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:30:16.97ID:T4XYjYgx
自分たちが他スレ嵐てんのに自分たちにワッチョイ付ける訳ない。己のやってることを顧みろ
0480デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:30:24.22ID:5bV//KSp
>>477
そう思うならワッチョイスレ盛り上げろよ
せめてpart6埋めてからワッチョイpart7を立てて盛り上げる方向にしろよ
0482デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:35:38.48ID:5bV//KSp
「荒らされるよりは過疎るほうがマシ」って言いながらこのスレに書き込んでワッチョイpart6使ってないのってどういうことなの
0483デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:38:33.24ID:5nlTHbBf
そんなにワッチョイが嫌なんだね。じゃあ次スレはワッチョイ有りにしよう。別にデメリット殆ど無いし。
0484デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:39:58.52ID:5bV//KSp
それ語尾wがワッチョイなし立ててそっちが盛り上がって使われないワッチョイpart15が打ち捨てられる未来しか見えない
0485デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:41:14.03ID:8lssQzCw
>>483
ワッチョイ有りRustスレは既に2つもある >>478
ここワッチョイ無しRustスレの次スレはもちろんワッチョイ無し
両方あれば全員に不満はない
0487デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:43:29.58ID:5bV//KSp
>>486
やってみてもいいけどワッチョイなしが過疎ったら責任とって埋めろよ
0488デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:45:38.16ID:5bV//KSp
>>487
ワッチョイなしじゃなくてワッチョイありざ過疎ったらの間違い
0490デフォルトの名無しさん
垢版 |
2022/03/13(日) 19:59:09.05ID:8lssQzCw
ここワッチョイ無しRustスレはいつも通り
ワッチョイ無しで次スレを立てることになる
ワッチョイ有りRustスレは既に2つある>>478
両方あれば全員に不満はない
0491デフォルトの名無しさん
垢版 |
2022/03/13(日) 20:25:42.25ID:vwVaodxg
よしでは方針を発表しよう

そのワッチョイありスレはおじさんが謎にageてるから
いまだに存在しているものと認識している
つまり既に侵食済みなので捨てる

Part15からワッチョイありスレとして継続していく
異論がなければこれで行く
0492デフォルトの名無しさん
垢版 |
2022/03/13(日) 20:39:16.20ID:5bV//KSp
確かによく見たら4は腐ってるな
でも6は使えるだろ。使ってくれ
0494デフォルトの名無しさん
垢版 |
2022/03/13(日) 20:41:14.82ID:aISbrcWr
それはワッチョイに効果がないことを示してるだけでは
報復のような行動や分断を産む議論は思う壺だと思う
黙ってNGに放り込めばいい
0495デフォルトの名無しさん
垢版 |
2022/03/13(日) 20:55:14.52ID:xFLia2nf
そもそもワッチョイにデメリットは無くてメリットだけなんだからカジュアルに入れればいいじゃん。
一人だけ急にここはワッチョイ無しスレの系譜なんて言い出した人もいるけど。そんな系譜無いし。
0496デフォルトの名無しさん
垢版 |
2022/03/13(日) 20:58:11.86ID:5bV//KSp
デメリットはどうせ分裂してワッチョイ15という過疎放置スレが無駄に出来ることだけなので、そうなった時にちゃんと埋めてくれるならなんのデメリットもない
0497デフォルトの名無しさん
垢版 |
2022/03/13(日) 21:04:18.91ID:r2YIM0KL
ワッチョイ必要だと思うならごちゃごちゃ言わずにさっさと自分で立てろよ
スレ立てくらい出来るだろ
0498デフォルトの名無しさん
垢版 |
2022/03/13(日) 21:19:00.22ID:d8CKnCLn
ワッチョイだから過疎ったんじゃなくてスレを複数作ったから過疎ったってことよ
スレを使い分けようって時点で問題児だらけデース!ってアピールしてるよ

今回のunsafeおじさんが暴れてた頃に誰もワッチョイスレに誘導しなかったところを見ると、存在すら忘れてたんじゃないか?
https://mevius.5ch.net/test/read.cgi/tech/1532697692
↑火種になりそうな人、話題は全部ワッチョイに誘導しようね。火種に触る人もワッチョイに行こうね
0499デフォルトの名無しさん
垢版 |
2022/03/13(日) 21:35:47.25ID:zl9/rhni
タイトルが同じだと数字が小さいスレに人がよりつかないのは当然なので
質スレと議論スレにでも分割して議論スレをワッチョイスレとして新たに始めればいいんじゃない?
議論したいってことみたいだから

誰も立てないからここ2回連続してスレ立てたけど
立てたらワッチョイガーとか繰り返し言われるのはさすがに腹が立つよ
問題は荒らしを相手にしてる人たちなのに
0500デフォルトの名無しさん
垢版 |
2022/03/13(日) 21:48:32.41ID:YWz/r5zq
ま、次スレからワッチョイでいいやん
荒らし目的の人はサヨナラしてくれていいやん
スレがノイズまみれになるのは目が滑ってしんどい
0501デフォルトの名無しさん
垢版 |
2022/03/13(日) 21:51:18.28ID:SWhadnJY
強引な変更には断固反対
少なくとも現状のワッチョイなしのスレも残すべき
0503デフォルトの名無しさん
垢版 |
2022/03/13(日) 22:12:56.56ID:e39Fa4ck
別にワッチョイにしたかったら両方作ればええやんw
俺は両方に反応するからw
ワッチョイなら一週間はNG設定変えなくていいんじゃないのw
ただ被るやついても俺のせいにするなよw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0504デフォルトの名無しさん
垢版 |
2022/03/13(日) 22:14:37.13ID:R0s3zSYd
荒らしてるのはGoの連中だろ。
報復するべし。
0506デフォルトの名無しさん
垢版 |
2022/03/13(日) 22:19:11.42ID:e39Fa4ck
いや・・・前1日で4人被ってたぞ俺にw 割と人の多い地域で割と大手のプロバイダだから被りやすいんだw
まあ俺は言ったからなw

Run cargo-geiger!
💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0507デフォルトの名無しさん
垢版 |
2022/03/13(日) 22:24:37.54ID:E9xpRPLy
どうでもええよ
今後もワッチョイの無いスレに書き込むし
スレが無ければワッチョイ無しで立てるから
0508デフォルトの名無しさん
垢版 |
2022/03/13(日) 22:49:01.50ID:ZP0/YH7Q
ワッチョイスレの方が過疎化して完走できないことになると誰でも予想できる
0509デフォルトの名無しさん
垢版 |
2022/03/14(月) 01:57:42.50ID:o6mZm6k9
rustならわっちょいつける方がらしくはあるな。言語思想がそういう感じだし。
0511デフォルトの名無しさん
垢版 |
2022/03/14(月) 07:47:11.82ID:6Z6ouTmU
Linux環境のrustでkbhit関数(キーイベントの取得)ってありますでしょうか?
コンソールアプリ(ゲーム)を作ときに使用しようと思ってまして
0512デフォルトの名無しさん
垢版 |
2022/03/14(月) 08:02:53.43ID:fAU8x8Os
真面目な質問はワッチョイありに書き込んでワッチョイ無しスレから誘導すればいいよ。

ワッチョイ無しスレは過疎らないし、ワッチョイスレは荒らしNGできるし文句言うやつは荒らし以外おるまい。
スレの再利用もできるしな。
0513デフォルトの名無しさん
垢版 |
2022/03/14(月) 11:19:45.82ID:ptWJKaRn
https://tech.aptpod.co.jp/entry/2021/12/03/070000

これとかそれっぽい?
でもcratesはそれっぽい名前の奴ほど放置ライブラリという特長があるから正直調べ方がわからん
0517デフォルトの名無しさん
垢版 |
2022/03/14(月) 16:56:04.09ID:U570WKgz
# 俺様はcrosstermに一票w
cargo install cargo-edit cargo-geiger
cargo new crossterm_example
cd crossterm_example
cargo add crossterm
cat >src/main.rs <<EOF
use std::time::Duration;
use crossterm::event::{poll, read, Event, KeyCode};
use crossterm::terminal::{enable_raw_mode, disable_raw_mode};
use std::io::Error;
fn main() -> Result<(), Error> {
enable_raw_mode()?;
loop {
if poll(Duration::from_millis(1_000))? {
let event = read()?;
println!("Event::{:?}\r", event);
if event == Event::Key(KeyCode::Esc.into()) {
break;
}
} else {
println!(".\r");
}
}
disable_raw_mode()
}
EOF
cargo build
cargo run
cargo geiger

# Run cargo-geiger!
# 💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0518デフォルトの名無しさん
垢版 |
2022/03/14(月) 23:31:15.69ID:zZd4y2TR
>>511
Rustで書いてもstdinへの設定自体は他の言語の時と全く同じ
以下C言語風でRust的に書けるnixクレート使用

まずstdinがエコーされたり改行まで入力されないのを解除
let mut stdin = stdin();
let mut termios = tcgetattr(stdin.as_raw_fd())?;
termios.local_flags &= !(LocalFlags::ECHO | LocalFlags::ICANON);
tcsetattr(stdin.as_raw_fd(), SetArg::TCSANOW, &termios)?;
これでstdin.read()で1文字ずつ入力キーを得られる

次に入力がない時にブロックされないように設定
let mode = fcntl(stdin.as_raw_fd(), FcntlArg::F_GETFL)?;
let mode = OFlag::from_bits_truncate(mode);
fcntl(stdin.as_raw_fd(), FcntlArg::F_SETFL(mode | OFlag::O_NONBLOCK))?;
これで入力がなくてもstdin.read()がすぐに返ってくる

あとは自分の好きな仕様で例えば
let mut input = [0; 1];
let code = match stdin.read(&mut input) {
Ok(_) => Some(input[0]),
Err(ref err) if err.kind() == ErrorKind::WouldBlock => None,
Err(err) => Err(err)?,
};
これで入力ASCIIコードがOptionで得られる

他にも例えば非同期とチャネルを使ってインタフェースを洗練して
ノンブロッキングにせずともread()とチャネルへのsend()を繰り返す
というキー入力専用の非同期タスクを作って
使う側ではチャネルからpoll_recv()で入力があるか見るとか
あるいはそもそも入力なしという状態を得る必要がないならば
その非同期タスクでread()がある度に指定クロージャを呼び出すなど
0519デフォルトの名無しさん
垢版 |
2022/03/14(月) 23:33:12.59ID:zZd4y2TR
ちなみにstdinからのASCIIコード取得では不満で
もっとrawレベルのイベントが欲しいならば
libevdevをRustで扱えるevdev-rsを使う
0521デフォルトの名無しさん
垢版 |
2022/03/17(木) 08:28:29.04ID:H9cH52GC
regex crateの問題って
外部ユーザー入力の正規表現をパースして使っていた時に
めっちゃ複雑な正規表現だとDoS攻撃になっちゃう恐れがあったという話か
0522デフォルトの名無しさん
垢版 |
2022/03/17(木) 22:36:27.41ID:IHLBrgoM
よほどのことがない限り
外部のユーザに正規表現を入力してもらうケースは無さそうだよな
0525デフォルトの名無しさん
垢版 |
2022/03/18(金) 12:41:29.69ID:slshVm4c
1st, 2nd 3rd, 4th, 5th, 6th, ..., Nth ←コレw

# Run cargo-geiger!
# 💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0527デフォルトの名無しさん
垢版 |
2022/03/18(金) 13:55:50.66ID:B5OelSHS
いやいやいやいやいやいやいやいやいやいや
うそやろ?だまされないぞ!( `・ω・´)
0528デフォルトの名無しさん
垢版 |
2022/03/18(金) 14:22:27.69ID:2Ztz8OnF
起源は何かなEmacs Lispにもあるし相当古そう
(nth N LIST)
Return the Nth element of LIST. N counts from zero. If LIST is not that long, nil is returned.
0529デフォルトの名無しさん
垢版 |
2022/03/18(金) 14:29:42.95ID:7XcvYw+s
色んな言語で使われている
Lispでnthはリストのn番目を返す
C++でstd::nth_elementはn番目を基準とする並べ替え
CSSで:nth-child()はn番目を選択
など
0533デフォルトの名無しさん
垢版 |
2022/03/18(金) 15:55:18.13ID:rmmV0EJL
定数時間でアクセスできないものに添え字を使うのは紛らわしいからやってないのでは
あとイテレータの場合nextが&mut selfを要求するのでIndexは実装できないし
IndexMutを実装するにしても0..n番目の要素をconsumeするから添え字のセマンティクスに合わないと思う
0534デフォルトの名無しさん
垢版 |
2022/03/18(金) 15:57:14.32ID:d7SFtIuN
コストが高かったり危険だったりするものは字面の上でも目立って欲しいしな。
0535デフォルトの名無しさん
垢版 |
2022/03/18(金) 16:12:59.80ID:slshVm4c
iteratorは原則順次アクセスだから、原則ランダムアクセスな添字は一般的ではないw
何でも聞いてしまう子は想像力がやや不足しているw

# Run cargo-geiger!
# 💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0537デフォルトの名無しさん
垢版 |
2022/03/18(金) 16:22:51.49ID:8ZTH26QZ
>>532
自由に添え字でアクセスしたい時はcollect()する
もちろんcollectはその分のコストがかかるけど他の言語では常にそのコストを強制されてるのだから
もし必要ならばRustでもそのコストを払えばよい
0538デフォルトの名無しさん
垢版 |
2022/03/18(金) 17:17:28.19ID:rmmV0EJL
>>532
昔は RandomAccessIterator があったけど unstable のまま rust 1.2.0 で deprecate されたみたい
https://doc.rust-lang.org/1.3.0/std/iter/trait.RandomAccessIterator.html
> trait has not proven itself as a widely useful abstraction for iterators, and more time may be needed for iteration on the design

C++やDには random access iterator はあるけど、 rust では今のところ必要ないという判断みたい
0539デフォルトの名無しさん
垢版 |
2022/03/18(金) 17:40:43.61ID:RcRFkS5N
>>538
それは内部でメモ化のコストを払うだけだからね
どうしても残したいならtake/take_while等してcollectでもいい
一方でnthはメモ化コストゼロ
0540デフォルトの名無しさん
垢版 |
2022/03/18(金) 18:26:51.78ID:rmmV0EJL
>>539
RandomAccessIteratorはslice::Iterなどランダムアクセスできるイテレーターに実装されてるトレイトなのでメモ化のコスト云々は関係ないよ
0541デフォルトの名無しさん
垢版 |
2022/03/18(金) 22:57:59.74ID:l4s3ZEj8
>>537
ヒープ確保と解放はコスト高いけど
定数もしくは上限Nがある時は
collect::<ArrayVec<_,N>>()でスタックに確保できる
0542デフォルトの名無しさん
垢版 |
2022/03/19(土) 00:16:53.31ID:Ul4y/GRp
ある型 T がトレイト A とトレイト B を実装していることという制約はたとえば以下のように書けますが、

struct Foo<T: A + B> {
state: T
}

ここで T がトレイト C を実装して「いない」という制約を付ける (C を実装していたらコンパイルエラーにする) 方法はありますか?
0543デフォルトの名無しさん
垢版 |
2022/03/19(土) 01:34:14.63ID:Ksx+z9b2
なさそう
0544デフォルトの名無しさん
垢版 |
2022/03/19(土) 10:14:06.85ID:Ul4y/GRp
直接的にトレイトが実装されていないことを指定することは出来ないようですが
optin_builtin_traits を使えば表現は出来そうですね。
Rust ユーザー向けのドキュメントが見つからないんですがこれって stable なんですかね?
0546デフォルトの名無しさん
垢版 |
2022/03/19(土) 19:35:20.82ID:mtaqaIpW
始めたばっかでよくわかんないんだけど、https://docs.rsって公式か何かのまともなサイトなの?
10進数の小数が使いたくてhttps://docs.rs/rust_decimal/latest/rust_decimal/#これ見てたんだけど、sourceってところ押したらよくわからんものが表示されてしまう・・・・
0548デフォルトの名無しさん
垢版 |
2022/03/20(日) 01:49:46.57ID:oj1vR2vz
docs.rsは公式サイトだけど内容はオープンソースで登録されたソースコード(コメント)から
機械的に生成してるだけだからちゃんとしてるとは限らない
sourceは生成元のソースコードのリンクになってて説明が分からんかったらソース読めってスタンス
0549デフォルトの名無しさん
垢版 |
2022/03/28(月) 17:41:10.51ID:T53tBXly
始めたばっかでよくわかんないんだけど、ちょっとコードを書いただけで.unwrap()だらけになってしまう
もう、3行に1つは.unwrap()、ひどいと1行に3箇所ぐらい.unwap()だ
素人目に見ても流石におかしいように見えるも、解決法がよくわからないぜ
0550デフォルトの名無しさん
垢版 |
2022/03/28(月) 17:42:54.07ID:T53tBXly
.unwrap()ってさっきまで沢山打ってたのに、1箇所打ち間違ったぜ
0551デフォルトの名無しさん
垢版 |
2022/03/28(月) 18:04:16.18ID:4U9zlcIi
まずはif let試してみたら?

if let Ok(v) = r {v使ったほにゃらら}
if let Some(v) = o {v使ったほにゃらら}
0552デフォルトの名無しさん
垢版 |
2022/03/28(月) 18:35:07.91ID:GscKI9M9
>>549
エラーなどの分岐が発生しうる時に
必ず正常値だと確信できる場合、もしくは、正常値でなければpanic終了してよい場合に
unwrap()を用いる

逆に言えば上記の場合でなければ
unwrap()を用いてはいけない

エラーなどの有無による分岐処理が必要とされている場面なのだから
if letやmatchや?オペレータ(=エラー時に即return)を用いなければならない
0554デフォルトの名無しさん
垢版 |
2022/03/28(月) 18:52:11.66ID:3OxWqSrL
rustでCのライブラリラップしてるけどまじでわからんこと起こりまくってて泣きそう
構造体に保持したはずのハンドラが不可解なタイミングで消えてつらい
Cにも疎いからしんどすぎる
0555デフォルトの名無しさん
垢版 |
2022/03/28(月) 20:40:56.66ID:BmyJew6n
>>554
それはさすがにCでのメモリ管理とRustでのメモリ管理とそれらの違いを把握できていることが最低条件
0556デフォルトの名無しさん
垢版 |
2022/03/28(月) 23:00:56.50ID:51Y1Thh9
このスレに識者がいるという錯覚wwww

# Run cargo-geiger!
# 💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0557デフォルトの名無しさん
垢版 |
2022/03/28(月) 23:06:14.30ID:labVp7ij
>>556
C/C++/Rustスレでも次世代言語Rustスレでも暴れ回って嫌われてるようですねガイガーくん
ここRust本スレには来ないでもらえますか?
0558デフォルトの名無しさん
垢版 |
2022/03/28(月) 23:21:53.41ID:ie9Ayk2m
>>553
それがいいね
対処方法はコード次第だから一部でも晒さないと一般的なアドバイスに留まってしまう
0560デフォルトの名無しさん
垢版 |
2022/03/29(火) 10:43:23.37ID:4onO4vig
>>559
うまくラッピングしてあってもCライブラリの内部の参照とかのあたりがうまくRustの所有権システムに乗らなくてしんどいことが多々あるから仕方ないことな気がする
0561デフォルトの名無しさん
垢版 |
2022/03/29(火) 13:05:38.54ID:jPLnZtHI
ハンドラのトラブルで思い浮かぶのはDropで解放する機能を実装したのにCopy可能になってるケースかな
数値型で表現される場合が多いからCopy不可の型で包まないとCopy先で解放されたりして事故りやすい
基本的にDropトレイトとCopyトレイトを混ぜるのはNG
0563デフォルトの名無しさん
垢版 |
2022/03/29(火) 22:49:23.99ID:zunmlMTL
>>557
え?なんで?w
# Run cargo-geiger!
# 💀💀💀☢☢☢☢💀💀💀 !!!! Rust is ☢UNSAFE☢ !!!! 💀💀💀☢☢☢☢💀💀💀
0564デフォルトの名無しさん
垢版 |
2022/04/03(日) 01:32:58.40ID:1As0eesQ
https://github.com/diesel-rs/diesel/blob/v1.4.4/examples/postgres/getting_started_step_1/src/schema.rs
https://diesel.rs/guides/getting-started.htmlの一部分)
このアロー演算子みたいなのが並んでいる部分って、どういう意味の文法なんですか?
一見してセッターかクロージャーなのかと思いきや、全然違うようで!?・・・・これは一体何なんですか????
0566デフォルトの名無しさん
垢版 |
2022/04/03(日) 02:40:58.52ID:1As0eesQ
>>565
マクロはわかんなかった、ありがとう!
ゆっくり調べてくる!
0567デフォルトの名無しさん
垢版 |
2022/04/04(月) 15:56:50.90ID:k6lsU7ys
こういうのがエラーになるんだが、なんで?
エラーメッセージは Sized が満たされてないとか出るんだけど
dyn とか Box ってこういう使い方をするもんじゃないの?

let mut foo = Box::<dyn Fn() -> usize>::new(|| 1);
foo = Box::<dyn Fn() -> usize>::new(|| 2);
0568デフォルトの名無しさん
垢版 |
2022/04/04(月) 16:47:46.89ID:y2zkcNcq
>>56
現状のrustではBox::newの引数に渡すのはコンパイル時にサイズが決まる型でないといけないから
dyn Fn() -> usize 型の値は渡せない

以下みたいに Box::new() で作った Box<T> 型の値を Box<dyn ...> にキャストするとやりたいことできると思う

https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=e02762a4d2df4aed2c5396251cd0a07c
0571デフォルトの名無しさん
垢版 |
2022/04/04(月) 23:27:32.81ID:tN0jAerG
let mut foo: Box<dyn Fn() -> usize> = Box::new(|| 1);
foo = Box::new(|| 2);
// ↓ このケースならばFn()使わずともfn()で行ける
let mut foo: Box<fn() -> usize> = Box::new(|| 1);
foo = Box::new(|| 2);
// ↓ さらにBoxも不要となる
let mut foo: fn() -> usize = || 1;
foo = || 2;
0572デフォルトの名無しさん
垢版 |
2022/04/04(月) 23:30:29.31ID:Uk+ayJmh
unwrapじゃなく;がunwrapの代わりになったらよかったのに、構文解析に;なんてもう使ってないでしょうに
0573デフォルトの名無しさん
垢版 |
2022/04/04(月) 23:41:54.63ID:3iHsJPtq
>>572
なぜ?
>>552にもあるけどunwrapなんて非常に特殊な時のみ使うもの
論理的にNoneやErrではないと保証できる場合は使うべきだが頻度も限られる
残りはNoneやErrの時にpanic終了という簡易エラー処理の場合でしかunwrapは使われない
その簡易エラー処理をしたい場合でも?オペレータでエラーを最上位に集めて1カ所だけエラー表示を設けるとpanic unwrapを無くせる
0574デフォルトの名無しさん
垢版 |
2022/04/05(火) 04:14:10.02ID:opdT/MNM
>>572
文は式と区別するため必ず「;」を伴う
例えば関数やブロックの最後(=「}」の直前)に
「;」があると文となり返り値が()となる
「;」がないとその式の値が返り値となる
そしてブロックやif-elseやloopはその値の式なので文を形成する最後に登場する時は「}」の直後に「;」が来る
このように他のプログラミング言語とは異なりRustでは「;」の存在は重要である
0575デフォルトの名無しさん
垢版 |
2022/04/05(火) 07:02:36.93ID:l+kYPJyP
ブロックの最後の式がブロックの評価値になるのはRubyもそうだよ
だからと言って;にunwrap割り当てろとは思わないけど
0576はちみつ餃子 ◆8X2XSCHEME
垢版 |
2022/04/05(火) 11:45:54.41ID:AUzgrMft
unwrap はそれなりに目立つべきだろう。
一文字でどうにかするのはよろしくない。
0577デフォルトの名無しさん
垢版 |
2022/04/05(火) 15:21:06.80ID:owP7OoVB
unwrap連打することもあるんだからないな
他の言語みたいにunwrapを!で書けるようにするほうがマシ
0579デフォルトの名無しさん
垢版 |
2022/04/05(火) 17:27:14.20ID:jhOIIm2D
使いにくく書きにくくさせることで
馬鹿に知らず識らずマナーを強いてるんだよ

だからJavaでアクセッサ書くのダルいと怒ってるのと
rustでmutってタイプするのダルいと怒ってるのと
unwrapってタイプするのダルいと怒ってるのと

言ってる人はみなおなじバカ
ちなみに馬鹿に迎合してプロパティを準備してみせたウルトラバカ言語がC#
0583デフォルトの名無しさん
垢版 |
2022/04/05(火) 19:39:53.86ID:RVaVR3wo
unwrap()は論理的に安全に剥がせると明確になる特殊な場合のみ使うべきもの
見てすぐ明確でない時はコメントを付けること推奨
0584はちみつ餃子 ◆8X2XSCHEME
垢版 |
2022/04/05(火) 20:30:38.50ID:AUzgrMft
エラーメッセージ中で便宜上のライフタイム (?) として '1 というのが出てくることがあるけど、
これは一個目の引数のライフタイムという解釈でいいのかな?
0585デフォルトの名無しさん
垢版 |
2022/04/05(火) 20:31:56.58ID:iTms6SBF
unwrap()はリリースビルドでコンパイルエラーにして欲しい
Elmみたいにデバッグビルドでのみ使えるって感じで
0587デフォルトの名無しさん
垢版 |
2022/04/05(火) 20:45:42.53ID:RriiMuS9
>>585
論理的に剥がして安全なことをコンパイラが追いかけてくれるならそれもありだけど
現状で全面unwrap禁止は無理
0589はちみつ餃子 ◆8X2XSCHEME
垢版 |
2022/04/05(火) 20:54:37.54ID:AUzgrMft
unwrap を排除したらそれぞれで unwrap みたいなものを定義して使うようになっちゃうのがオチだよ。
0591デフォルトの名無しさん
垢版 |
2022/04/05(火) 21:09:00.11ID:ks20fz6N
>>590
論理的に起きない場合にexpectは単なるコードの無駄
エラー発生時にパニック終了していいプログラムで補完エラーメッセージとしてexpectを使う
0592デフォルトの名無しさん
垢版 |
2022/04/05(火) 21:21:53.89ID:m6fZyHop
>>591
趣味の問題な気がするけどその理屈だと論理的に起きない場合はコメントの無駄とならない?
それともコミュニティーで広く普及してる慣例があるのかしら
0593デフォルトの名無しさん
垢版 |
2022/04/05(火) 21:39:41.29ID:u7gEIfJv
一般的に、論理的に正しいがコードを見てすぐに把握できない可能性がある場合は、コメントを付ける慣例
0596デフォルトの名無しさん
垢版 |
2022/04/06(水) 00:19:00.36ID:QeRv7PuV
>>575
Null条件演算子とか他言語には一般的になって来てるけど、ライブラリでしかないはずのOption,Resultが言語の中核みたいになってるRustが
採用するとは思えない。Option条件演算子?
0597デフォルトの名無しさん
垢版 |
2022/04/06(水) 00:29:51.46ID:NjGChFO7
他でのNull合体演算子つまりNull時にデフォルト値とする演算はRustではunwrap_or
もちろんそれら他の言語ではT型そのものにNullがありミスを防げないが
RustではT型とOption<T>型に分かれているためミスが起きない
0598デフォルトの名無しさん
垢版 |
2022/04/06(水) 03:59:22.01ID:pOKs9eQ1
いや言語的な特性のこと言ってるわけじゃねーからwいちいち知識疲労で解説しなくていいからw
0601デフォルトの名無しさん
垢版 |
2022/04/06(水) 10:07:13.82ID:LgAnKe/v
>>600
try構文使わずとも書けるよね

fn main() {
let a = Some([[1, 11], [2, 22], [3, 33]]);
let x = (|| Some(a?.last()?.first()? * 100))();
assert_eq!(x, Some(300));
}
0607デフォルトの名無しさん
垢版 |
2022/04/07(木) 07:08:56.80ID:GJZ5/Xn8
クロージャ(ラムダ)の即時実行は他の色々な言語でも行なう頻出パターン
Rustでは他にもforやwhileから値を返したい時などにもクロージャの即時実行で行なう
0608デフォルトの名無しさん
垢版 |
2022/04/07(木) 07:19:00.45ID:M1TIObhS
これって、公開するメソッドのの数だけディスパッチャメソッドが増えてく感じなの?
https://tourofrust.com/81_ja.html
結構めんどくさいような気もするんだけど・・・・こういうのってエディタの拡張とかが勝手やってくれたりとか、支援みたいなのあるの???
0609デフォルトの名無しさん
垢版 |
2022/04/07(木) 07:36:57.92ID:GySucWIC
>>608
プログラマーは全く何もしなくてよい
dyn Traitの場合はメソッド数分の関数ポインタを持つディスパッチ用テーブルが各使用型毎に自動的に生成されて実行時に自動的に適用される
impl Traitの場合は使用メソッドの関数がモノモーフィゼーションすなわち各使用型毎にコンパイル時に展開される
逆にプログラマーが自分で分岐処理する第三の方法としてenumに各使用形を収容してmatchによる分岐処理があってこの方法が有利になるケースもある
0610デフォルトの名無しさん
垢版 |
2022/04/07(木) 10:32:38.29ID:bzCO3d2+
C++ だと静的な多相はテンプレートで、動的な多相は仮想関数 (抽象クラス) でやってるわけだけど、
Rust だと dyn だけで切り替えられるってわけだな。
0611デフォルトの名無しさん
垢版 |
2022/04/07(木) 12:45:48.26ID:Qjh8kwCx
>>608
tour of rustでRustに入門するのはやめたほうがいいぞ
中身が更新されてないしGoと違ってtourから始めるのは害にしかならないから
0612デフォルトの名無しさん
垢版 |
2022/04/07(木) 13:22:38.91ID:bzCO3d2+
わかる。
Rust の型システム・所有権システムは理屈が分かってないと慣れでどうにかなるもんではない。
理解した上でなら手を動かしてみるのは悪くないと思うけど。
0613デフォルトの名無しさん
垢版 |
2022/04/07(木) 15:06:14.55ID:pUyNlzjX
>>612
それはどんな言語も多かれ少なかれありそう
Cのポインタもそうだしね
0615デフォルトの名無しさん
垢版 |
2022/04/07(木) 18:20:36.61ID:6QFUvNfL
クロージャは引数と戻り値を推論してくれるからこそだね
関数でも、なんかの条件付きでもいいから推論してほしいわ
0617デフォルトの名無しさん
垢版 |
2022/04/07(木) 18:33:18.44ID:6J24GmAj
関数含むモジュールレベル定義の型推論はやろうと思えばできるけど
コンパイル時間への影響がでかいのと、ドキュメント的な意味で型を書いた方がわかりやすいという理由で
敢えて対応していないとどこかで読んだ気がする

とはいえ戻り値のimpl Traitは制限された形での型推論と言えるんじゃないかな
0618デフォルトの名無しさん
垢版 |
2022/04/07(木) 18:34:30.25ID:QZwctsvV
>>614
Rustでは型指定しなくて済む利点もあるしクロージャと関数の使い分けの一種じゃないかな
もちろん今回のケースはreturn値を取る別種のブロックがあれば済むけども
それをわざわざ導入しなくてもクロージャ即時呼び出しで十分
0619デフォルトの名無しさん
垢版 |
2022/04/08(金) 04:35:42.40ID:fis9zD2L
Rustのコンパイルの遅さは型推論とかじゃなく、cargoという非常に悪い仕組みのせい
0628デフォルトの名無しさん
垢版 |
2022/04/12(火) 11:33:29.72ID:/UwhBms2
プログラム開始時点での有効性を保証できないから何となくだけどコンパイラの事情で無理そう

&'staticって↓みたいな使い方もできるからLazyだとBの参照先が初期化済みか分からない
static A: u32 = 0;
static B: &'static u32 = &A;
0629デフォルトの名無しさん
垢版 |
2022/04/12(火) 11:37:37.75ID:9tHmQ2kh
nightlyのstd::lazy::Lazyではなく
stableでも使えるonce_cellを使用
そのコードと同じ例がこれで動く

use once_cell::sync::Lazy;

static LAZY: Lazy<i32> = Lazy::new(|| 92);

fn main() {
let a: &'static i32 = sub();
println!("{}", *a);
}

fn sub() -> &'static i32 {
&*LAZY
}
0630デフォルトの名無しさん
垢版 |
2022/04/12(火) 11:44:54.53ID:mYiJhF+M
あーなるほど
なぜか'staticでmutableなのがstatic、immutableなのがconstと勘違いしてました
constって使用の度に式展開するやつだったんですね
temporary valueなんて無いじゃんとか無限に悩んでた

ありがとうございます
0633デフォルトの名無しさん
垢版 |
2022/04/15(金) 00:23:00.39ID:jmI/h0lt
>>613
プログラムのポインタ(メモリアドレスを参照するもの)は
ポインタのメタファだから元のポインタを知ってれば理解できるが、
substructural type systemはtype systemの一種でtype systemは
型理論を元にした体系的な理屈だから理屈が理解できなきゃ理解できないから全く別の話。

>>612の言う「慣れでどうにかなるもんではない」っていうのはつまり、
わかった気になってなんとなくで書いてるやつはまだ理解してないって話でしょ。
0636デフォルトの名無しさん
垢版 |
2022/04/15(金) 00:56:52.75ID:w32fyljo
>「慣れでどうにかなるもんではない」っていうのはつまり、
>わかった気になってなんとなくで書いてるやつはまだ理解してないって話でしょ。

全然違う。
型システムより先に文章を理解する訓練をした方がいいぞ。
0637デフォルトの名無しさん
垢版 |
2022/04/15(金) 01:20:52.56ID:+d47tguH
>>612
他の言語と同様にRustもそんな難しいことしていないから大丈夫
論理とメタ的な考え、例えば高階やジェネリクス等、ができる普通の人ならばRustの理解は容易い
0639デフォルトの名無しさん
垢版 |
2022/04/15(金) 08:41:02.84ID:WzhbtFPJ
100点オジサンや複製オジサンみたいな自分は理解してるつもりの勘違いさんが一番迷惑
0640デフォルトの名無しさん
垢版 |
2022/04/15(金) 08:59:01.96ID:uOSWEI+/
>>638
普通のプログラマーなら他の言語でクロージャ(ラムダ等)くらいはさすがに使ったことあるから高階は大丈夫なはず
ジェネリクスもスクリプト言語などの動的型付け言語なら計らずともそのままジェネリックな関数となってる

そこでRustでのみ必要となる概念はそのジェネリックな関数内を安全な操作とするためのトレイト境界の指定
これはコンパイラがエラーとして教えてくれるため指定を忘れることがない
だから普通のプログラマーなら大丈夫じゃないかな
0641デフォルトの名無しさん
垢版 |
2022/04/15(金) 10:17:08.40ID:xMTiu+TR
相変わらず複製おじさんは不勉強でキツイな
「普通の人」は他の言語でジェネリック使ったことあるからこんな恥ずかしい長文を書かない
0642デフォルトの名無しさん
垢版 |
2022/04/15(金) 10:53:34.01ID:aXBzZfpz
そうでなくRustではtrait境界が足りなければコンパイルエラーで指摘されるからスクリプト言語から来た人でも困らないって話やろ
0646デフォルトの名無しさん
垢版 |
2022/04/15(金) 12:26:07.26ID:hAkRYyug
>>640
「クロージャ(ラムダ等)くらいはさすがに使ったことある」からといって「論理とメタ的な考え……ができる」ではないことは論理的に明らか。
全然論理的な考えができていない>640自身が反証になっているね。
0651デフォルトの名無しさん
垢版 |
2022/04/15(金) 14:19:47.21ID:Xm9+ELTI
所有権でよくわからないって言えばさあ
fn asdf() -> &str{
let s = "jkl";
s
}
みたいにした時に、関数を抜ける際にstrのライフタイムが尽きちゃう訳じゃない
でも逆になぜ&strしかないのに、どうして関数を抜けるところまでstrのライフタイムが持つのか?そこら辺がよくわからねえな
&strを通じてstrを所有できているのであれば、&strをリターンできても良いような気もするのに・・・・どうなってんの?
0652デフォルトの名無しさん
垢版 |
2022/04/15(金) 15:21:50.13ID:k/yGxJzN
>>651
fn asdf() -> &str

fn asdf<'a>() ->&'a str
のようにlifetimeを省略した記法なんだけど、
この 'a は引数にも現れないし何の寿命に対応するか分からないからエラーになっちゃう

今回の文字列リテラルみたいにプログラム開始から終了まで存在するデータへの参照なら、
プログラム開始から終了までを意味する 'static を使うことはできる
fn asdf() -> &'static str

また以下のように引数に参照が登場する場合は、
戻り値の寿命は暗黙的に引数と同じだと見なされる
fn asdf(a: &str) -> &str

fn asdf<'a>(a: &'a str) -> &'a str
となるということ

この辺の仕組みは lifetime elision でググると情報出てくるよ
0653デフォルトの名無しさん
垢版 |
2022/04/15(金) 15:35:47.27ID:/A+hDicd
>>647
>>648
両方やってみて結局こうなったがまだよく分からん

https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=aafabd8057a50f537f9ff410c03461d2

yが借用中にもかかわらずdropされたというふうに読めるけど、f(&mut y)が終わった時点で借用も終わってるから問題無いのでは?
でも試しにこの後yをどうこうするコード付け足してみると、どうも借用しっぱなしになってるっぽいエラーばっかり出るのよな
0654デフォルトの名無しさん
垢版 |
2022/04/15(金) 16:44:22.79ID:tw5ISWTc
>>651
&’static strが返されてるからだよ
リテラルはstatic扱いだと思っておけばいい

>>652
fn asdf<'a>() ->&'a strと書いても’>>651のケースはエラーにならないよ
0657デフォルトの名無しさん
垢版 |
2022/04/15(金) 19:50:10.79ID:rQzdCva+
ありがとう!
なんかちょっとズレたエラーメッセージだなと思っても、省略・推論されているなんて夢にも思わなかったから意味がわんなかったぜ!
0658デフォルトの名無しさん
垢版 |
2022/04/16(土) 15:01:46.93ID:Tmn9GDW2
Rustって参照をベクターに持てる?
0660デフォルトの名無しさん
垢版 |
2022/04/16(土) 17:14:58.83ID:Tmn9GDW2
>>659
サンクス
0661デフォルトの名無しさん
垢版 |
2022/04/20(水) 18:37:23.24ID:3eLEi52G
Rust 入門者です。
全く実用的な意味はなく練習として符号無し整数を桁ごとに返すイテレータというものを考えていたのですが
同じ制約を重複して書くことになってしまい不格好な気がします。
https://ideone.com/qOmnhW
ベテランが華麗に書いたらどんな風になりますでしょうか。
それとも Rust ではこれで良いものなのでしょうか。
0663デフォルトの名無しさん
垢版 |
2022/04/20(水) 22:38:14.51ID:3eLEi52G
>>662
ありがとうございます。
たしかにこのコードではトレイト Digits にスーパートレイトを付ける必要はないですね。

想定を後出しにして誠に申し訳ないのですが、これはライブラリ (クレート) としてまとめようとしているつもりでした。
ここに書かれていない未知の型にトレイト Digits を実装することがあり得るという意味です。

問題になるのは、 Digits のスーパートレイトを消してしまうとどんな型でも Digits の実装自体は出来てしまうということです。

// ↓ Digits にスーパートレイトを付けなければこう書くこと自体は出来てしまう。 この段階でエラーになって欲しい。
struct Foo {}
impl Digits for Foo {}

そしてメソッド digits を呼出すところでエラーになります。

let bar = Foo {};
for x in bar.digits() { // ← ここでエラーになる
println!("{}", x);
}

逆に言えば digits を呼出さなければエラーになりません。
どうせ使えないことがわかっているならトレイトの impl の段階でエラーであって然るべきだという判断が
重複する制約を書いた意図です。
メソッドがイテレータを返すなんていうのはよくあることだと思うので、
いちいち重複したことを書かかなくて済むような何かがあるんじゃないか……という想像から質問した次第です。
0664デフォルトの名無しさん
垢版 |
2022/04/20(水) 23:00:49.13ID:uLqNeO4/
>>663
そういう前提ならばこんな感じで impl の方の制約を T: Digits に変えるのはどうじゃろ
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=6bd0ab54e4cbd88ca2a0502f9e74315d

あと T::Error: std::fmt::Debug についてはどの trait の associated type に対する制約か分かり辛いから
<T as std::convert::TryInto<u8>>::Error: std::fmt::Debug,
としても良いかもね
0666デフォルトの名無しさん
垢版 |
2022/04/21(木) 13:57:26.69ID:Ast3pmta
数値にメソッドを生やすメリットが思いつかないからこれだけでいいんじゃない?

fn digits<T>(n: T) -> impl Iterator<Item=T>
where T: Clone + PartialEq + From<u8> + std::ops::DivAssign + std::ops::Rem<Output=T>
{
itertools::unfold(n, |n| (*n != T::from(0)).then(|| {
let rem = n.clone() % T::from(10);
*n /= T::from(10);
rem
}))
}

fn main() {
let foo: i64 = 9165731750932755204;
for x in digits(foo) {
println!("{x}");
}
}
0667デフォルトの名無しさん
垢版 |
2022/04/21(木) 14:14:33.93ID:Q5xBjMYc
実用上は関数で十分だろうけど、Rustって整数のプリミティブ型にもたくさんメソッドあるし、
メソッドを生やすのが流儀なのかな、って俺も思ってたけどどうなんやろ?
0668663
垢版 |
2022/04/21(木) 14:30:15.62ID:9+GFB0OX
>>667
過剰にトレイトを作るなというのはドキュメントのどこかに書いてあったような気がする。
0669デフォルトの名無しさん
垢版 |
2022/04/21(木) 22:20:02.87ID:NWAfliAT
>>666の関数をメソッド化しようとしたら
traitやimplの中では関数はimpl Iteratorを返せないと怒られた
この制限は将来緩和される可能性ある?
implでなく返す型を具体化したらコンパイル通って動いた
traitとimplでwhereのところが冗長な気がするけど両方とも外せない?

trait Digits<T> {
fn digits(self) -> itertools::Unfold<T, fn(&mut T) -> Option<T>>
where T: Clone + PartialEq + From<u8> + std::ops::DivAssign + std::ops::Rem<Output=T>;
}
impl<T> Digits<T> for T {
fn digits(self: T) -> itertools::Unfold<T, fn(&mut T) -> Option<T>>
where T: Clone + PartialEq + From<u8> + std::ops::DivAssign + std::ops::Rem<Output=T>,
{
itertools::unfold(self, |n| (*n != T::from(0)).then(|| {
let rem = n.clone() % T::from(10);
*n /= T::from(10);
rem
}))
}
}

fn main() {
let foo: i64 = 9165731750932755204;
for x in foo.digits() {
println!("{x}");
}
}
0671デフォルトの名無しさん
垢版 |
2022/04/22(金) 09:42:40.77ID:sg+qNIV4
>>670
こんな記述もできるようになるわけね
let displayable: impl Display = "Hello, world!";
const MY_CLOSURE: impl Fn(i32) -> i32 = |x| x + 1;
let x: impl Iterator<Item = i32> = (0..100).map(|x| x * 3).filter(|x| x % 5);
0672デフォルトの名無しさん
垢版 |
2022/04/22(金) 11:24:39.82ID:QUxpZq2Z
>>669
traitとimplのfnの型制約なくしてimplの制約にするのはどう?
Tに対する制約は実装に依るものなのでimplが課してるものとみなした方が自然な気がする
0675デフォルトの名無しさん
垢版 |
2022/04/22(金) 12:09:33.52ID:L/Q81szU
>>674
where制約宣言の場所をメソッドfnからimplへ移動させることで結果的にtrait側で制約する必要がなくなるわけか
0676661
垢版 |
2022/04/22(金) 13:12:07.76ID:rYail8LQ
>>674
元々の想定では符号付きの場合を型の制約で排除したいと考えていました。
トレイトが実装されているかどうかだけでは必要な性質を満たしているかどうか判定しきれないと考えて
個別に実装する必要があるという判断をした次第です。
個々に人が判断するのではなく制約で包括的に判定するとしたら std::ops::Neg を実装して「いない」という条件を付ける
必要が出てくるかと思いますが、今の Rust だとそういう制約は付けられないですよね?
0677デフォルトの名無しさん
垢版 |
2022/04/22(金) 14:11:21.60ID:RekYcGSo
>>676
そこは汎用的に空のtrait Unsignedを空のimplで用意して使う
自分で用意してもいいが既にあるnum::Unsignedをトレイト境界に加えるだけで希望を叶えられる
0678デフォルトの名無しさん
垢版 |
2022/04/24(日) 14:55:18.07ID:SDl1bpLd
>>675
trait宣言でtrait境界制約しないメリットは他にもある
例えば文字列(例 "57261")に対するdigits()をimplできるようになってこの場合は別のtrait境界をimpl側で書くことになる

ただし別問題として現状ではまだ安定化していない2つの機能サポート待ち
1つ目はimpl Traitのspecializationでfor Tが既にあるところへfor Stringやfor &strできるようにするため
もう1つはGATs (general associated types)でイテレータで参照返しできるようにするため
0679デフォルトの名無しさん
垢版 |
2022/04/25(月) 18:30:29.96ID:5VI7zZaU
String の配列でパターンマッチしたいと考えていますが、
こういう書き方をすると String と &str を比較しているとして型が合いません。

fn main() {
let foo = [String::from("bar")];
let baz = match foo { ["bar"] => 1, _ => 2 };
}

かといって書けるパターンは制限があるので↓こう書くことも出来ません。

fn main() {
let foo = [String::from("bar")];
let baz = match foo { [String::from("bar")] => 1, _ => 2};
}

ガードを付けるかスライスの配列を作るかくらいしか方法はないですかね?

fn main() {
let foo = [String::from("bar")];
let baz = match foo { [ref x] if x =="bar" => 1, _ => 2 };
}

fn main() {
let foo = [String::from("bar")];
let bar = &foo.iter().map(|ref str|&str[..]).collect::<Vec<_>>()[..];
let baz = match bar { ["bar"] => 1, _ => 2 };
}
0680デフォルトの名無しさん
垢版 |
2022/04/25(月) 19:55:08.99ID:6A0Kp8FF
>>679
配列は長さ固定
長さが異なれば別の型となる
マッチングは全て同じ型でなければならない

つまり長さ1の配列パターンがあるならば全て長さ1の配列
つまり配列としてマッチングする必要がない
実際には長い配列で先頭だけマッチングしているとしてもfoo[0].as_str()でよい

おそらく例として簡略化して書いたのだろうがもう少し具体化した方がアドバイスを受けやすい
0682デフォルトの名無しさん
垢版 |
2022/04/26(火) 02:22:33.26ID:9/mVSM+b
問題はそこじゃなくて &[String] をパターンマッチする方法がないってことだよね
0683デフォルトの名無しさん
垢版 |
2022/04/26(火) 02:43:40.86ID:uT+rLtYK
Stringのままだと、文字列のマッチはガードでやるしかなそうだし、
その場合なら &str にしてからマッチしたほうが良さそうだね
0684デフォルトの名無しさん
垢版 |
2022/04/26(火) 13:29:24.27ID:v9kFaZ9R
変換するならばヒープ使わずに配列mapかな
match foo.map(String::as_str) はちょっと惜しかった
0687デフォルトの名無しさん
垢版 |
2022/04/26(火) 16:05:15.07ID:MauoWn9e
別の配列になるけど
mapがなぜかselfを要求する
つまりStringの配列に対して何もできない
Stringの長さの配列すら生成不可能
Copy実装型の配列に対してしかmapを使えないのではないか
0688679
垢版 |
2022/04/26(火) 16:52:48.66ID:dc8onzA9
>>687
map が要求する self ってのはイテレータのことですよ。
配列の所有権が移ったりはしませんよ。
0690679
垢版 |
2022/04/26(火) 17:05:45.05ID:dc8onzA9
>>689
失礼しました。
同名のものが配列にもあるんですね。
0691デフォルトの名無しさん
垢版 |
2022/04/26(火) 17:08:44.26ID:9/mVSM+b
>>687
長さの配列は元のStringへの参照を保持するわけではないから生成可能
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=1389138f28b6679332ad660d8920ea5e

元のStringがconsumeされるのでStringへの参照を持つようなデータへの変換はできない
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=f358e19998b508fe1955ea5274a7daf5

元の配列がdropされて良いならCopyな型に対してしか使えないということはないよ
例えば構造体の一部フィールドだけ変更するみたいな用途にも使える
0693デフォルトの名無しさん
垢版 |
2022/04/26(火) 17:20:49.70ID:6GFvJMAy
&strの配列に変換してから比較すると変換時と比較時とで2周するのと
比較対象がconst相当じゃないとだめなのでguardのほうがベターなケースが多いと思う
0694デフォルトの名無しさん
垢版 |
2022/04/26(火) 17:38:44.61ID:+plNly3p
配列mapは新たな配列を作る
つまり配列map自体が元の配列をdropするわけではない
Copyを実装していない型の時はmoveとなるため結果として元の配列がdropされる
Copyを実装している型の時はmoveが起きないため元の配列もそのまま使える

// Copyを実装していない型の場合
#[derive(Debug)]
struct XM(i32);
let a1 = [XM(1), XM(2), XM(3)];
let a2 = a1.map(|XM(n)| n);
println!("{a2:?}");
// println!("{a1:?}"); // エラーとなる

// Copyを実装している型の場合
#[derive(Debug,Clone,Copy)]
struct XC(i32);
let a1 = [XC(1), XC(2), XC(3)];
let a2 = a1.map(|XC(n)| n);
println!("{a2:?}");
println!("{a1:?}"); // エラーとならず元の配列も残っている
0696デフォルトの名無しさん
垢版 |
2022/04/26(火) 18:33:28.01ID:WcuXDkX5
配列mapは
Stringの配列を&strの配列に変換できないけど
&Stringの配列を&strの配列に変換できるよ
つまり
Stringの配列を&Stringの配列に変換できればよくてそれがeach_ref()
0697デフォルトの名無しさん
垢版 |
2022/04/26(火) 19:46:56.99ID:/uwAuiMA
each_ref()はまだstableじゃないので
Stringを&strにしておく方法でヒープ(Vec)を使わないならこうかな
let x: [String; 3] = ["foo".into(), "bar".into(), "baz".into()];
let y: ArrayVec<&str, 3> = x.iter().map(|s| &**s).collect();
let z = match &y[..] { ["foo", ..] => 1, _ => 2 };
0699デフォルトの名無しさん
垢版 |
2022/04/26(火) 21:13:08.58ID:YFyFIjJ4
iter→map→collectだけのコードが分かりにくい、って初心者でも言わないだろw
3行目の数値1と2は謎だが>>679の質問者のコードそのままだな
0703デフォルトの名無しさん
垢版 |
2022/04/26(火) 23:34:34.80ID:sIujHvVn
>>700
sが&Stringだから
*sがStringになって
**sがstrになって【Derefによって】
&**sが&strになる
というのを知った時は衝撃的でした
0706デフォルトの名無しさん
垢版 |
2022/04/27(水) 10:03:29.93ID:wZJ3zy1g
定数パラメータなら最近サポートされた

#[derive(Debug)]
struct Matrix<const N: usize>([[f32; N]; N]);

impl<const N: usize> Matrix<N> {
fn identity() -> Self {
let mut m = Self([[0.0; N]; N]);
for i in 0..N {
m.0[i][i] = 1.0;
}
m
}
}
fn main() {
let identity: Matrix<3> = Matrix::identity();
println!("{:?}", identity);
}

ちなみに
struct Matrix<const N: usize>([f32; N*N]);
はできなかった
0707デフォルトの名無しさん
垢版 |
2022/04/27(水) 11:10:01.91ID:zNaA7U6C
演算子 ? のことを個人的にトライ演算子と呼んでいたんですが、
公式には単に「operator ?」としか書いていないみたいですね。
口頭で言うときにはどういう言い方で呼びます?
0710デフォルトの名無しさん
垢版 |
2022/04/27(水) 11:32:02.01ID:Xa5DwGtB
try-catchが将来入ることを考えると、 ? の役割は try と言うより throw 相当と考えた方が良いのかな
0716デフォルトの名無しさん
垢版 |
2022/04/27(水) 15:54:47.56ID:zNaA7U6C
後置にするにしても普通のメソッドみたいになんらかの名前で呼び出すようにしたら
それがプログラムの流れを変える制御構文的なものであることが分かり難くなるだろうし、
後置の演算子という選択はとても良いと思う。
0718デフォルトの名無しさん
垢版 |
2022/04/27(水) 16:17:57.00ID:QP7+22WQ
>>716
後置の演算子にするのはRustの使い方なら当然だと思うが
声に出して読めない(人によって読み方がバラバラになってる)のが問題

try file.read()時代は誰でも同じように読めた
file.read()? は読めない

.awaitはオペレータを導入したとしてもawaitオペレータという呼び方でみんな同じように読めるから何の問題もない
0719デフォルトの名無しさん
垢版 |
2022/04/27(水) 16:26:14.46ID:nimuFt37
file.read().await? よりも
file.read()待? でいいんじゃないかな
オペレータ記号は仮に「待」とした
0721デフォルトの名無しさん
垢版 |
2022/04/27(水) 19:33:26.91ID:quTQsckx
>>713
Cowにmapってどういう仕様にするの?
どちらの場合でも統一的に具体型へ変換ならcow.as_ref()かcow.into_owned()のどちらかだろうし
0723デフォルトの名無しさん
垢版 |
2022/04/27(水) 19:42:04.29ID:du++GsRu
>>722
cowを変換して何かにするのではなく
cowそのままでそれ自体を統一的に書き換えるならto_mutだね
0724デフォルトの名無しさん
垢版 |
2022/04/28(木) 10:44:53.84ID:9IEjG0GC
バイナリデータを受け取るいい方法ってある?
やりたいことはGETリクエストの結果送られてくるバイナリデータをファイルに保存したい

CやJavaなら適当なchar配列(Javsはbyte)でいっぱいまで受け取ってファイルに書き出すを繰り返せばいいってわかるんだけど、似たようなことをRustでやりたい
0727デフォルトの名無しさん
垢版 |
2022/04/28(木) 11:40:54.23ID:ZJVxwbem
綺麗に抽象化したレイヤを作ろうとしたら C や Java とは違った雰囲気にはなるだろうけど、そういうのは後回しや。
綺麗だろうが汚かろうがまずはやってみたらええんや。

ところで「汚かろう」を変換したら「北中朗」と出てきた。 誰やお前は。
0728デフォルトの名無しさん
垢版 |
2022/04/29(金) 00:19:46.61ID:H/gm+2Cv
勉強中
Cow<T>の取りうる値は
・Cow::Borrowed(T)
・Cow::Owned(<T as ToOwned>::Owned)
とのことなので ToOwned を調べてみると
 ToOwned::Owned = Borrow<T>
つまり impl Borrow<T> for S の時に
・Cow::Borrowed(T)
・Cow::Owned(S)
となる関係だと分かった
そしてこんな状況で使えるぽい
impl Borrow<[T]> for Vec<T>
impl Borrow<str> for String
impl Borrow<CStr> for CString
impl Borrow<OsStr> for OsString
impl Borrow<Path> for PathBuf
0729デフォルトの名無しさん
垢版 |
2022/04/30(土) 03:53:42.52ID:cIBooLV/
16進数文字列から整数への変換を標準ライブラリでやるにはどうすればよいですか?
0730デフォルトの名無しさん
垢版 |
2022/04/30(土) 07:53:08.90ID:tlhDM02s
Cだと次のように書けるエンディアンを調べるプログラムはどう書いたらいいですか?

int x = 0x12345678;
char *p = &x;

for( int i = 0; i< sizeof(int); i++ ){
fprintf(stderr, "%X\n", *p++ );
}

CでもWarningは出ますが
0732デフォルトの名無しさん
垢版 |
2022/04/30(土) 19:04:20.68ID:1Px+JTey
>>730
どうしても表示したいならば
直訳するとこんな感じ

use std::mem::size_of;

fn main() {
let x: i32 = 0x12345678;
let p = &x as *const i32 as *const u8;
for i in 0..(size_of::<i32>() as isize) {
eprintln!("{:x}", unsafe { *p.offset(i) });
}
}
0733デフォルトの名無しさん
垢版 |
2022/04/30(土) 22:34:14.48ID:jfGNsSDk
原則としてはエンディアンに依存しない形で書いて入出力のときだけ from_le とか to_le とかで処理するのが良い作法だとは思うけどね……。
0734デフォルトの名無しさん
垢版 |
2022/04/30(土) 23:10:52.66ID:prwxQRGd
>>729
仕様がわからないからジェネリックにOption<T>で返すとしてこうなるのかな
stdにCheckedAddとCheckedShlがないから自作するところを略してnum::から借りた

use num::traits::{CheckedAdd, CheckedShl};

fn parse_hex<T>(s: &str) -> Option<T>
where T: From<u8> + CheckedShl + CheckedAdd
{
s.bytes()
.try_fold(T::from(0), |acc, b|
acc
.checked_shl(4)?
.checked_add(&T::from(byte_to_hex(b)?))
)
}

fn byte_to_hex(b: u8) -> Option<u8> {
if b'0' <= b && b <= b'9' {
Some(b - b'0')
} else if b'A' <= b && b <= b'F' {
Some(b - b'A' + 10)
} else if b'a' <= b && b <= b'f' {
Some(b - b'a' + 10)
} else {
None
}
}

fn main() {
assert_eq!(Some(65535), parse_hex::<u16>("ffff"));
}
0737デフォルトの名無しさん
垢版 |
2022/05/01(日) 13:20:24.87ID:R2/wU8kY
>>734 これ標準ライブラリにあるで
use std::usize;
fn main() {
let z = usize::from_str_radix("ffff", 16).unwrap();
assert_eq!(z, 65535);
}
0738デフォルトの名無しさん
垢版 |
2022/05/01(日) 18:53:34.40ID:AHIbQu1a
現状のstr::parse()とstr::FromStr traitのコードは以下のようになっているが
fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
FromStr::from_str(self)
}
trait FromStr {
type Err;
fn from_str(s: &str) -> Result<Self, Self::Err>;
}

このFromStrをAddなどと同様にOutput指定付きにしておけば良かったのではないか?
trait FromStr<Output = Self> {
type Err;
fn from_str(s: &str) -> Result<Output, Self::Err>;
}

そうすると以下のようにOutputをSelf以外でimplできるようになるから
impl<T, const N: usize> FromStr<Output = T> for Radix<T, N> { ... }
現在ある>>737のfrom_str_radix()が使えないu128出力などにも拡張できて
"ffffffffffffffff".parse::<Radix<u128, 16>>()
と使えるようになるから中途半端なfrom_str_radix()を廃止してparse()に統一できる
0739デフォルトの名無しさん
垢版 |
2022/05/01(日) 20:49:11.67ID:4fkon5Y4
u128でもfrom_str_radix使えるのはさておき
便利そうだけどそんなtraitにFromStrという名前が付くのは違和感あるなあ
0740デフォルトの名無しさん
垢版 |
2022/05/01(日) 21:11:45.93ID:RoZQG5Cx
>>739
え?
例えば&strからIPv4やIPv6アドレスへの変換ですらRust標準ライブラリはFromStrを使ってるよ
0742デフォルトの名無しさん
垢版 |
2022/05/01(日) 21:15:48.33ID:Z7VnuZFm
T::from_str が T (Result<T, E>) 以外の型を返す関数なのは違和感あるでしょってことが言いたかった
0743デフォルトの名無しさん
垢版 |
2022/05/01(日) 21:41:43.18ID:PdC+0ci4
Radix<u128, 16>::from_str が Radix<u128, 16> を返してもいいだろうけど
中身はu128しかないのだから FromStr<Output = u128> で u128 を返せると便利、って話だよね
XXX::from_str の XXX 部分は文字列をどう解釈するかの指定
だから通常は Output = XXX と同一になるけど、そこを指定できると互換性を保ったまま利便性を向上できるという話だよね
0744デフォルトの名無しさん
垢版 |
2022/05/01(日) 22:19:59.78ID:Z7VnuZFm
提案自体は分かるけど T from str と読めるメソッドが T 以外の何者かを返すのは不適切な命名では?
別のtraitでやるべきだと思う
0745デフォルトの名無しさん
垢版 |
2022/05/01(日) 22:44:03.61ID:4fkon5Y4
>>741
そういうこと
不用意に複雑にするのはよろしくないし、stdにある必要も無いと思う
どうしてもやりたければ↓みたいに自分で実装できるし、
もっと複雑になってきたら適切なパーサライブラリでも使用するのがいいだろう
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f450a3bdf5eab0f1849b4945aede582f
0746デフォルトの名無しさん
垢版 |
2022/05/01(日) 23:00:56.52ID:4fkon5Y4
ところでこれ書いてて気づいたけど i8::from_str_radix("80", 16) とかは PosOverflow になるんですね
16 だからできそうな気がするだけで、考えてみればそうかという感じだけど
0747デフォルトの名無しさん
垢版 |
2022/05/01(日) 23:26:05.49ID:fn7me9b4
>>746
自作でもそのへんのエラーを返したい時あるけど
ParseIntErrorのnewが無い、かつ、kindがprivateなため返せなくて困ったことがある
0749デフォルトの名無しさん
垢版 |
2022/05/02(月) 15:22:57.69ID:mbEFGeje
cargo が粗悪

スグにリソースを喰らい尽くす特級禍呪怨霊
0751デフォルトの名無しさん
垢版 |
2022/05/02(月) 18:47:44.24ID:G4+2oPiW
どちらも参照で構造体のオプションをそのメンバーのオプションにするもっと短い表記ないのかな
struct1.map(|struct1| struct1.member2)
0753デフォルトの名無しさん
垢版 |
2022/05/02(月) 23:24:08.49ID:J2M173NZ
メンバーを参照で返すならば
&struct1.member2 と&が必要
元のOptionのstruct1はもし参照が外側ならば
struct1.as_ref() で内側の参照にしておくことが必要
0754デフォルトの名無しさん
垢版 |
2022/05/03(火) 01:23:35.68ID:PKeASy9M
struct1.map(|struct1| &struct1.member2)
長くていいなら
struct1.and_then(|struct1| Some(&struct1.member2))
0755デフォルトの名無しさん
垢版 |
2022/05/03(火) 02:02:53.67ID:PFPUtHlZ
すごく曖昧な日本語だけど普通に読むなら
構造体のオプションも、そのメンバーのオプションも、どちらも参照という意味じゃないの?

struct Foo<‘a> {
 bar: &’a Option<Bar>
}

↑こういう構造体を&Option<Foo>の形で受け取って内包する&Option<Bar>で返したいという話
知らんけど
0758デフォルトの名無しさん
垢版 |
2022/05/03(火) 09:09:45.26ID:PFPUtHlZ
そういうことか
だとmapするのが一番シンプル
$0やitのようなクロージャ用の暗黙的変数はないから明示的に渡すのは必須
struct1.map(|x| x.member2)
0760デフォルトの名無しさん
垢版 |
2022/05/03(火) 12:00:16.10ID:4pk6EqdP
>>758
多段(メンバーのメンバー)を考えるとmapは見辛いし長い
なのでtryブロックもしくはstableならクロージャで?オペレータが良い
0762デフォルトの名無しさん
垢版 |
2022/05/03(火) 15:24:00.08ID:PFPUtHlZ
>>760
tryブロックはまだしもクロージャの即時実行は意図を曖昧にするだけだから極力避けたほうがいいと思う
多段で長くなるような処理なら関数化して型を明記しておいたほうが後で楽
クロージャは型推論と外部変数のキャプチャで最初は楽できるんだけどね
0763デフォルトの名無しさん
垢版 |
2022/05/03(火) 16:33:58.30ID:+yoZQWc3
十文字かそこらで終わるレベルならクロージャでも別に悪くはないと思うけどね。
多少の無駄は最適化で消えてなくなるだろうし。

ただ、そう思っていると後からごちゃごちゃ処理が増えてわけわからんようになるのが世の常というものなんや……。
0764デフォルトの名無しさん
垢版 |
2022/05/03(火) 16:54:12.49ID:Huay3i5k
多段になった時にクロージャだと「?」を重ねてすぐ書けたのですが
クロージャではなくmapを使う場合はどのように書けばいいのでしょうか?

fn main() {
struct S<'a> { o: Option<&'a str> }

let s1 = Some(S { o: Some("abc") });
let s2 = Some(S { o: Some("pq") });
let s3 = Some(S { o: None });
let s4 = None;

for s in &[s1, s2, s3, s4] {
let s = s.as_ref();
let a = (|| s?.o?.get(2..=2))();
println!("{a:?}"); // Some("c"), None, None, None
}
}

このクロージャで動いている例で教えてください
0768デフォルトの名無しさん
垢版 |
2022/05/03(火) 17:31:47.54ID:8YvdvoC0
>>765
同じこと(構造体の有無)をしてるのに
さっきはmapで今回はand_thenかよ
一貫性がなくわかりにくくなってるぞ
0769デフォルトの名無しさん
垢版 |
2022/05/03(火) 17:39:05.78ID:4J+xsrZX
ここまで見てきて感想

// 一貫性もあり分かりやすいクロージャ
let a = (|| s?.o)()
let a = (|| s?.o?.get(2..=2))();

// 一貫性もなく分かりにくいクロージャ+α
let a = s.map(|s| s.o);
let a = s.and_then(|s| s.o?.get(2..=2));
0772デフォルトの名無しさん
垢版 |
2022/05/03(火) 19:05:25.07ID:+FrLoUDt
このand_then方式が何故わかりにくくなっているかというと
let a = s.and_then(|s| s.o?.get(2..=2));
先頭のsだけを特別扱いしていることが原因

例えばこのように先頭を無条件に真となるようにすると
let a = Some(true).and_then(|_| s?.o?.get(2..=2));
その後のs?もo?も同じ扱いになり常に一貫した表記となる

上記から無駄な部分を省いてしまうと
let a = (|| s?.o?.get(2..=2))();
結局クロージャのみとなる
つまり最初の部分だけ特別扱いをやめたことで表記が一貫した
0773デフォルトの名無しさん
垢版 |
2022/05/03(火) 19:50:20.80ID:OPUNSUqX
>>762
それは視野が狭すぎる
クロージャ類の即時実行は他のプログラミング言語でも普通に使われる
特にRustではインライン展開されて付加コスト無し
そのため様々なcrateでクロージャの即時実行が使われている
標準ライブラリ内部では先行してtryブロックが有効となったためそちらへ移行した
つまりクロージャの即時実行で書いておけばtryブロックがstableとなった時に移行しやすいメリットもある
0775デフォルトの名無しさん
垢版 |
2022/05/03(火) 23:10:41.13ID:0DNzmsNq
標準ライブラリ内では今はtryに移行しているけど多用されているな。
激しいのだと"?"が6個も出てくる。

https://doc.rust-lang.org/src/core/iter/adapters/flatten.rs.html#322
> let upper = try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };

これもstableでは (|| fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?))(); で動く。
したがってstableではクロージャーを即時実行する形で書き、
いずれtry_blockがstableになったらそのまま置き換えがベストな方法。
0777デフォルトの名無しさん
垢版 |
2022/05/03(火) 23:49:23.79ID:EjxGzJz/
tryはクロージャ代用で困っていないが
GATsとimpl specializationを早く安定化して欲しい
0778デフォルトの名無しさん
垢版 |
2022/05/04(水) 10:04:54.12ID:BCVMJms8
try blockが解決しようとしてる問題を理解すればIIFEの何が問題なのかも分かる
0781デフォルトの名無しさん
垢版 |
2022/05/04(水) 21:42:20.03ID:uizzY+8f
Rustの練習でFizzBuzzを書いてみたのですがもっと速くできますか?

fn main() {
let mut n = 1;
loop {
if n % 15 == 0 {
println!("FizzBuzz");
} else if n % 5 == 0 {
println!("Buzz");
} else if n % 3 == 0 {
println!("Fizz");
} else {
println!("{n}");
}
n = n + 1;
}
}
0782デフォルトの名無しさん
垢版 |
2022/05/04(水) 23:33:28.78ID:5IOUV+X2
>>776
型を指定する方法が未解決なのでいつになるかは不明
年単位で先の話になると思っておいたほうがいい
0783デフォルトの名無しさん
垢版 |
2022/05/05(木) 00:18:26.00ID:s+BOvh+C
FizzBuzzは単純すぎて実行時の剰余算とその分岐を避けるくらいしか改善できないんじゃないか
あとはマジックナンバーを避けて更にRustっぽく書くとこうかな
const FIZZ: usize = 3;
const BUZZ: usize = 5;
const FIZZ_BUZZ: usize = FIZZ * BUZZ;
fn main() {
(0..FIZZ_BUZZ)
.cycle()
.enumerate()
.skip(1)
.for_each(|(n, i)| match TABLE[i] {
Some(s) => println!("{s}"),
None => println!("{n}"),
})
}

type Table = [Option<&'static str>; FIZZ_BUZZ];
const TABLE: Table = make_table();
const fn make_table() -> Table {
let mut table = [None; FIZZ_BUZZ];
let mut i = 0;
while i < FIZZ_BUZZ {
table[i] = match i {
i if i % FIZZ_BUZZ == 0 => Some("FizzBuzz"),
i if i % BUZZ == 0 => Some("Buzz"),
i if i % FIZZ == 0 => Some("Fizz"),
_ => None,
};
i = i + 1;
}
table
}
0784デフォルトの名無しさん
垢版 |
2022/05/05(木) 05:24:26.06ID:DUJQpJw8
ダサい例として挙げられていたwhileによるカウントアップが使われているけど
const_forはまだまだ先が長そうね
そのためにはIterator
そのためにはimpl Trait
0785デフォルトの名無しさん
垢版 |
2022/05/05(木) 08:21:51.44ID:y9k2LxGs
>>781
https://ideone.com/QkAorv
速くはできてないと思うけど
ifじゃなくてmatchを使った例
fn main() {
for n in 1..101 {
match (n % 3, n % 5) {
(0, 0) => println!("fizzbuzz"),
(0, _) => println!("fizz"),
(_, 0) => println!("buzz"),
_ => println!("{}", n),
}
}
for n in 1..101 {
println!("{}", n.fizzbuzz())
}
}
あと下の例はenumとtraitを使ってみた
enumとtraitのほうはrustっぽく使えてるかどうか自信なし
0786デフォルトの名無しさん
垢版 |
2022/05/05(木) 09:45:30.02ID:l2X3qjWl
forってかなり高度な構文だよなと改めて思う
constで使えるようになるのはかなり先になりそうだな...
0789785
垢版 |
2022/05/05(木) 15:13:48.30ID:ddifXjp/
https://ideone.com/G4kYRi
enumで持つ整数の型を固定しないようにした
最初からこうすべきだった
0790デフォルトの名無しさん
垢版 |
2022/05/05(木) 17:40:31.65ID:FeY8iOM4
カルビーが12月から全社員を対象にした副業制度を導入。
多様な働き方のさらなる進化を目指す

カルビー「何でもテレワーク」工場視察からゆるい勉強会まで

建設業界の常識を覆す“攻め”の働き方改革【週休3日制】を4月からトライアル導入
残業大幅減でも利益は昨対比2倍に上昇!

労働時間すべて社外勤務OK。トラック業界の“先駆者”が新制度

日野、「副業」許可制度を新設 “経験”広げて本業に生かす

ダイハツが副業容認を本格検討、その狙いと新しい働き方とは?

ダイドーグループ、「副業・副業受け入れ制度」を導入

Afterコロナ時代を生き抜くべく、ダイドードリンコが「自社人材の副業」と
「他社からの副業人材の受入れ」を開始
0794デフォルトの名無しさん
垢版 |
2022/05/05(木) 21:39:31.34ID:ddifXjp/
>>792
必要に応じて実装してもらえればいいかな?
impl FizzBuzz for f32 {
fn fizzbuzz(&self) -> FizzBuzzResult<&Self> {
match (self % 3.0, self % 5.0) {
(0.0, 0.0) => FizzBuzzResult::FizzBuzz,
(0.0, _) => FizzBuzzResult::Fizz,
(_, 0.0) => FizzBuzzResult::Buzz,
_ => FizzBuzzResult::Num(self),
}
}
}
fn main() {
for n in 1..101 {
println!("{}", (n as f32).fizzbuzz())
}
}
正直言うとfn fizzbuzz<T>(n: T) -> FizzBuzzResult<T>
みたいな関数を書けないかと思って先に試してみたけど
中でリテラル使って計算してるのが祟って書けなかった
0795デフォルトの名無しさん
垢版 |
2022/05/05(木) 21:51:56.06ID:KLOlIWxl
>>794
実装コードが異なる型は別実装でいい
しかし今回は同じ実装コードだろ
そういう時はジェネリックに書くのがRust
0797デフォルトの名無しさん
垢版 |
2022/05/06(金) 00:00:07.68ID:U1cwKpJU
>>796
一般的にジェネリックにするためのトレイト境界となるパーツのトレイトは個別に型列挙してimplする必要がある
そこではマクロが有用
パーツとなるトレイトを利用してプログラミングすれば列挙の必要性がない
0798デフォルトの名無しさん
垢版 |
2022/05/06(金) 00:18:49.47ID:lqMO+ITd
パターンに定数を使うことは可能です。

fn baz(x : usize) -> usize {
const ZERO : usize = 0;
match x {
ZERO => 1,
_ => 2
}
}

しかしトレイト内の定数で型が確定しない状況ではそれがパターンに使える定数なのかどうかわかりません。
(のでエラーになります。)

trait foo {
const ZERO: Self;
fn bar(&self) -> usize {
match self {
Self::ZERO => 1, // エラーになる
_ => 2
}
}
}

このとき Self がパターンに現れることが出来る型であるという制限を付けることは可能ですか?

(>>794 の定数だけ impl すればメソッド自体は共通化できるかなと思って試みたけどこれをどうにもできなくて困った)
0800デフォルトの名無しさん
垢版 |
2022/05/06(金) 06:31:06.34ID:ALxSds4A
>>798
その問題もTraitの関数でconstを返せないため現状では無理
だからmatchパターンでは使えないがifガードでなら使える
 
>>789のうちimpl FizzBuzzだけ以下に変更

use std::ops::Rem;
impl<T> FizzBuzz for T where T: Copy + From<u8> + PartialEq + Rem<Output=T> {
fn fizzbuzz(&self) -> FizzBuzzResult<&Self> {
let zero = T::from(0);
match (*self % T::from(3), *self % T::from(5)) {
(x, y) if x == zero && y == zero => FizzBuzzResult::FizzBuzz,
(x, _) if x == zero => FizzBuzzResult::Fizz,
(_, y) if y == zero => FizzBuzzResult::Buzz,
_ => FizzBuzzResult::Num(self),
}
}
}

これでu128でもf64でも動く
0802デフォルトの名無しさん
垢版 |
2022/05/06(金) 12:16:10.95ID:cmC85Voz
ざんね〜ん
f64はStepを実装していないので(1.0)..=(100.0)できませ〜ん
いっけね!
0804デフォルトの名無しさん
垢版 |
2022/05/06(金) 13:38:51.38ID:mCVU3PbX
impl XXX for T で where にだらだら制約書くやつは変に制約強くなりがちだから実装の共通化が目的ならマクロ使った方が良い
実装の共通化のために継承を使うようなもので、目的に対して不適切な手段を使っているように思う
0805デフォルトの名無しさん
垢版 |
2022/05/06(金) 14:08:08.87ID:cmC85Voz
パラノイアみたいにジェネリックジェネリック言う割にはそこだけ{integer}なのは気にしないんだ

FizzBuzzなんて>>781でいいんだよ
もっと意味のある仕事をしようぜ
0806デフォルトの名無しさん
垢版 |
2022/05/06(金) 14:14:00.63ID:xNV5dZfk
ジェネリックにするのも時間の無駄だが
traitにするのがそもそもガイキチ

>>781は無限ビジーループで論外
最低限でも関数の入出力は考えろ
0807デフォルトの名無しさん
垢版 |
2022/05/06(金) 14:15:08.65ID:gaqqfXMl
マクロ使うしかないんだけど、マクロの部分はエディタのサポートがちょっと弱くなるのが残念だよね
0808デフォルトの名無しさん
垢版 |
2022/05/06(金) 18:19:49.06ID:lqMO+ITd
FizzBuzz を過剰にジェネリックにする意味はないが、
ここではジェネリック化の手法を色々知るというのがトピックで FizzBuzz はただの例だよ。
0809794
垢版 |
2022/05/06(金) 18:53:54.80ID:13OIhPlc
>>797
> トレイト境界となるパーツのトレイトは個別に型列挙してimplする必要がある

もしよかったら具体的にどういうことか教えてちょ
不勉強すぎてまったくついていけない

>>798
> 定数だけ impl すればメソッド自体は共通化できるかな

定数だけimplするとは?

>>800
(´・∀・`)ヘー
勉強になりました
Fromってそうやって使うんやね

>>804
みんながどうやらマクロで解決してるらしいのは流れみて分かったが
具体的にはさっぱり分からんのでツライところ
おまえらって詳しくてスゴイわ
0814デフォルトの名無しさん
垢版 |
2022/05/06(金) 22:25:22.98ID:13OIhPlc
>>812
> マクロでtraitを実装する

(´・∀・`)ヘー
imple X for Yまるごとマクロの中に来るんやね
Rustのマクロについては調べたこと無かったけど
やっぱやりたいことはできるようになってそうで安心
ありがとうございました
0816デフォルトの名無しさん
垢版 |
2022/05/06(金) 23:24:33.89ID:lqMO+ITd
>>815
それいいな。
先にゼロと比較してから true にマッチさせる部分よりもゼロを作るテクニックのほうが面白いと思った。
0817デフォルトの名無しさん
垢版 |
2022/05/06(金) 23:27:51.66ID:BxCPOws/
>>801
i8で動かない原因はFromを使っているためなのでTryFromを使えばi8でも動く

use std::convert::TryFrom;
use std::ops::Rem;
use num::CheckedAdd;

fn fizzbuzz<T>() -> impl Iterator<Item=FizzBuzzResult<T>>
where T: Copy + PartialEq + CheckedAdd + Rem<Output=T> + TryFrom<usize>,
{
let [zero, one, three, five] = [0, 1, 3, 5]
.map(|n| T::try_from(n).ok().unwrap());
itertools::unfold(zero, move |n|
n.checked_add(&one).map(|new| {
*n = new;
match (new % three, new % five) {
(x, y) if x == zero && y == zero => FizzBuzzResult::FizzBuzz,
(x, _) if x == zero => FizzBuzzResult::Fizz,
(_, y) if y == zero => FizzBuzzResult::Buzz,
_ => FizzBuzzResult::Num(new),
}
})
)
}

fn main() {
for f in fizzbuzz::<i8>() {
println!("{f}");
}
}

ちゃんとi8の上限127で停止
0820デフォルトの名無しさん
垢版 |
2022/05/07(土) 02:27:17.25ID:xQfG7eKz
どっちがいいかどうかはともかくとして、817が使ったであろうnum-traitsのcrateのCheckedAddもマクロで実装されてるよん
こういうのはマクロになりがち
0821デフォルトの名無しさん
垢版 |
2022/05/07(土) 03:15:28.92ID:ZCh9Flgq
どちらも正しい
・基本的な性質のTraitは型を列挙してimplする →マクロになる
・それら以外のTraitは基本Traitを組み合わせる →Trait境界の列挙となる
0825デフォルトの名無しさん
垢版 |
2022/05/07(土) 08:35:04.90ID:VQro7qgS
現状はジェネリックじゃ実現できない事が多々あるから性能面を重視するならマクロになる
数値系は特に
0826デフォルトの名無しさん
垢版 |
2022/05/07(土) 10:48:47.74ID:RZMV7d1m
型パズルオナニストきついなぁ
長いコードをレスに直接貼りたがる性癖どうにかならんの?
0828デフォルトの名無しさん
垢版 |
2022/05/07(土) 12:04:47.91ID:yYzn+ZfL
>>825
マクロとtraitで性能が変わりうるのってどういう時?
traitだと回りくどい記述になりがちということ?
0829デフォルトの名無しさん
垢版 |
2022/05/07(土) 12:16:47.05ID:dujXhAGl
>>828
BigIntは参照で渡したいけどプリミティブ数値型は値で渡したい
traitだと値か参照かどっちかにしかできない、とかじゃねーの知らんけど
0830デフォルトの名無しさん
垢版 |
2022/05/07(土) 13:05:53.65ID:es6B5OyZ
>>827
トレイト境界を理解できないやつがいると思っちゃうところが相当ヤバいんですけど
さすオナ
0834デフォルトの名無しさん
垢版 |
2022/05/07(土) 17:58:20.41ID:gG9SW2bz
>>826
Rustに限った話じゃないけど、playground系で貼らないのは自己顕示欲の率直なあらわれだと思う
0835デフォルトの名無しさん
垢版 |
2022/05/07(土) 18:06:27.34ID:O43ZQkJC
辿れなくなる (サービスが終わったり障害が起こる) 可能性もあるから短いものはなるべく直接貼るようにしてる。
大抵は収まる大きさにならないけど。
5ch 自体が見れない場合はしょうがないんだが、話題に付随するコードが見れないときはだいぶんイラッとするぞ。
0837835
垢版 |
2022/05/07(土) 18:32:31.81ID:O43ZQkJC
>>836
すでに投稿されてるものを読む側の話なんだが……。
0838デフォルトの名無しさん
垢版 |
2022/05/07(土) 18:55:21.90ID:Dd8HOak9
俺も貼れるなら直貼りするわ
いちいち見に行くのも面倒だろうし
そもそも自己顕示欲ないなら貼らないしw
0840835
垢版 |
2022/05/07(土) 19:12:51.63ID:O43ZQkJC
>>839
話題が見れないときよりも話題は見れるのにコードが見れないほうがイラッとするという話なんやが。
0841デフォルトの名無しさん
垢版 |
2022/05/07(土) 19:25:31.02ID:RYRWOUip
ちゃんとコンパイルとrustfmt通したもの貼りたいからplayground使う
スマホからも確認できて便利だよ
0843835
垢版 |
2022/05/07(土) 20:14:55.20ID:O43ZQkJC
>>842
うん。 勝手にいらついてるよ。
でも俺は誰かをいらつかせないためになるべくレス内にコードを書くって話。
0845デフォルトの名無しさん
垢版 |
2022/05/08(日) 00:42:10.94ID:Q6fkz0I8
5chに貼られてインデントもないコードは読みづらいし、結局コピペして整形しなおすことになるんだから、最初からplaygroundとかを使って貼れよ
もちろんちゃんとコンパイルが通って実行可能な状態でな。
言及もせずにcrateやunstable機能使われてると、なかなか実行確認できずに面倒だからな

それが閲覧者のことを考えてる、ってもんだ
サービスダウンが心配なら、複数のサービスに貼り付けてくれればいいぞ、まあそこまではいらんけど
0850デフォルトの名無しさん
垢版 |
2022/05/08(日) 01:47:03.57ID:aBGW8DHe
連続した半角スペースがちゃんとインデントとして表示されるのは一部の専ブラとか使ったときだけ
通常のウェブブラウザではHTMLとして処理されて消える
0852デフォルトの名無しさん
垢版 |
2022/05/08(日) 02:08:11.23ID:aBGW8DHe
主張だなんて大げさな

ウンコが約1名いる
そのウンコはインデントしない
そのウンコは直貼りする

それだけの話だろ
0853デフォルトの名無しさん
垢版 |
2022/05/08(日) 02:15:49.76ID:0+ernfNx
スレの最初から見たけど全てのコードがインデントされてるな
1名だけインデントしていないとか言い出す人は何らかの精神病なんだろうけど
0854デフォルトの名無しさん
垢版 |
2022/05/08(日) 02:52:18.44ID:aBGW8DHe
二度手間だから最初からPlaygroundに貼りませんか?って話なのに
ウンコが何人いるかなんてどうでもいい話ばかり気にするのね
0857デフォルトの名無しさん
垢版 |
2022/05/08(日) 04:00:12.11ID:yk1Ip/5C
いちいち見に行くの面倒だからここでいいんじゃね
でも使いたい人を責めることはしないよ
0859デフォルトの名無しさん
垢版 |
2022/05/08(日) 07:15:54.25ID:slXg99Fw
どこの世界でも同じだが
特定の意見や特定の方針を他人に押し付ける人やイラつく人は嫌われる
0860デフォルトの名無しさん
垢版 |
2022/05/08(日) 07:38:34.92ID:yAkpoBe0
ブラウザにでっち上げた言語を無駄に抱き合わせることは、押し付けじゃないの?
0862デフォルトの名無しさん
垢版 |
2022/05/08(日) 09:09:22.14ID:DesCjmqL
ウンコード直貼りと自演擁護はいつもの複製おじさんだから
適当な所で切り上げないと時間の無駄だよ
0863デフォルトの名無しさん
垢版 |
2022/05/08(日) 09:37:03.03ID:Nx2GTU7H
>>862
> 自演擁護
これまたでかいブーメランだな、久々に見たわ
で、インデントされてない1名ってどれ?w
0864デフォルトの名無しさん
垢版 |
2022/05/08(日) 09:52:04.06ID:1JnUqrf/
うんこ等の汚い単語を使うのはいつものキチガイだから無視するのがよいかと
0866デフォルトの名無しさん
垢版 |
2022/05/08(日) 10:40:24.72ID:VSrRGkQQ
せめて技術的な話でやりあってくれめんすw
煽りオンリーは時間の無駄でつよ
0867デフォルトの名無しさん
垢版 |
2022/05/08(日) 11:27:48.48ID:nUQgQyI4
貼られたソースコードはクリック一つで自分の環境やplayground等に移せるようにしている
逆にplayground等に貼られたソースコードは自動引用表示してる
どちらもほぼ同じ表示となるため両派とも自由に好みのスタイルで貼ってくれて構わない
0869デフォルトの名無しさん
垢版 |
2022/05/08(日) 14:46:10.02ID:4M3U681r
最近はjaneでも連続半角スペースが表示されるようになってる
かなり短いコードじゃないと見にくいが
0872デフォルトの名無しさん
垢版 |
2022/05/08(日) 16:41:53.28ID:YFFn3It/
おまえらrustfmt使ったことないのか?
クリックで1つで呼び出せるようにしてるので
インデントが崩れていようが元が変なインデントだろうが綺麗に見やすく表示できてるぞ
他者に文句を言う前に自分で技術で解決しろ
0873デフォルトの名無しさん
垢版 |
2022/05/08(日) 16:41:56.65ID:f6r9nZo0
直貼りやインデントは置いといて
コードの中身の技術的な面で何がウンコなのかを書いてくれ
0874デフォルトの名無しさん
垢版 |
2022/05/08(日) 17:33:44.38ID:lkdR6fP8
おっしゃる通り
技術的な議論だけにしていただきたい
表示問題はrustfmt自動適用
0876デフォルトの名無しさん
垢版 |
2022/05/08(日) 17:55:41.35ID:hxmNE5v6
めんどくせーから5chでシンタックスハイライトとrustfmtとコード実行できるようにしとけ
0877デフォルトの名無しさん
垢版 |
2022/05/08(日) 18:08:39.11ID:pEnumwVx
各自の環境に合わせて様々な対応方法があるな
Webブラウザならブラウザ拡張でもいいしブックマークレットでもよい
専ブラは多種あり各々で可不可が違うのでノーコメント
自作ブラウザなら当然楽勝
ところでrustfmtは標準入出力かファイルだが公開ウェブサービスある?
無ければhyperで作ってローカルに動かして使う
0879デフォルトの名無しさん
垢版 |
2022/05/08(日) 18:25:54.88ID:Qi+3klcX
俺はウェブブラウザで見てるけど間にサーバを挟んでいるのでrustfmtもそこで呼び出すことにする
playgroundからのコード自動引用もやりたいが貼られたURLからrustコードを取ってくるにはどうすればいい??
0881デフォルトの名無しさん
垢版 |
2022/05/08(日) 21:46:56.59ID:CfKZzM4b
「独りよがりの長いコードを繰り返し直貼りするな」
「見る側がフォーマットすればいいだけ」

なんじゃこの流れ
フォーマッタは汚物浄化装置じゃないぞ
0882デフォルトの名無しさん
垢版 |
2022/05/09(月) 01:40:30.37ID:LU0ROcMI
プログラム板でコードが貼られて困る人はいないだろうけど
どうしても欲しい人はコード表示on/offボタンを付ければ良さげ
いずれにせよ各個人の好みの問題は各個人で解決すべき
0884デフォルトの名無しさん
垢版 |
2022/05/09(月) 03:29:00.32ID:ffvBu05T
技術面に触れないと突っ込まれそうなので、>>817についての個人的な感想ですが

Tのトレイト境界に関して、数が多くなるのは仕方の無いケースもあるが、この例では単に数が多いだけでなく、
CheckedAdd等の内部実装に踏み込んだトレイトまで指定されていて、その点が良くないと思います
例えばCheckedAddを実装していなくてもFizzBuzzできる型に対して、同じ関数を使うことができない
またCheckedAddを実装しているがより効率の良いアルゴリズムで実装できる型の場合でも、この関数では効率の悪いアルゴリズムで処理するしかない
ので>>822のようにFizzBuzzできるかどうかをtraitとして持たせ、実装詳細は各型に任せるのがよいと思います

こんなことで長文書くのも馬鹿馬鹿しいね
0885デフォルトの名無しさん
垢版 |
2022/05/09(月) 03:47:02.18ID:sZTgEcAj
>>884
その主張は全て間違い
checked addしなければオーバーフローしてプログラムが破綻するだけ
そしてchecked addはCPUレベルではオーバーフローフラグを見てるだけなのでコストゼロ
さらにCheckedAdd traitは任意の型に実装可能
0889デフォルトの名無しさん
垢版 |
2022/05/09(月) 11:09:02.87ID:oo5VwkGP
>>887
checked_addを使うか否かではなく
T: CheckedAddという強い制約の必要性について聞かれてるんだと思うよ
0890デフォルトの名無しさん
垢版 |
2022/05/09(月) 11:41:45.48ID:xlOpI0yW
Rustにおいてchecked_add (及び同等で返し方が異なるだけのoverflowing_add) は数値を扱う上でオーバーフローを起こさせないための必須の存在
そしてchecked_addは整数型ならばadd直後のCPUのoverflowフラグを見るだけだからオーバーフローを検出するために最もコストが低く済む存在
だからその手のものを素直にコーディングすれば必ず登場
そのtrait CheckedAddを使うのは違和感なく自然に思えるが他にどんな手段があると主張している??
0891デフォルトの名無しさん
垢版 |
2022/05/09(月) 12:15:35.42ID:RFFIBNHv
「ゼロからその型の最大値まで一個づつたどるイテレータ」
なんてもんに固執してるあたりがまずさいしょに珍妙

順序や範囲は他の理由で決定させて十分だと思う人は
イテレータとfizzbuzzをきれいに分離して考えてる
0892デフォルトの名無しさん
垢版 |
2022/05/09(月) 12:26:48.80ID:niJ+za4U
>>891
その件は最初にFizzBuzzの話が出てきたときに終わっていて単なる例にすぎない
話が分かりにくいならばもっと単純な例としてフィボナッチ数列イテレータでどうかな
ご存知だと思うけど足し算するだけの数列ね
0893デフォルトの名無しさん
垢版 |
2022/05/09(月) 12:37:12.80ID:ffvBu05T
そうか>>817が急に脈絡なくイテレータの話にし始めたのか

>>891に完全同意
適当なイテレータ持ってきて.map(fizzbuzz)でいいね
そっちはRem+PartialEqと、0と3と5を持ってくるための制約で済む、それなら自然だと思う
0896デフォルトの名無しさん
垢版 |
2022/05/09(月) 12:53:11.04ID:3SVLm32h
>>894
経験の違いじゃない?

関心事の分離を意識できないのは使い捨て感覚ででしかコードを書いたことのないからだと思う

組織で開発してたり長く維持する製品コードを書いた経験があればトイプログラムでも関数の責務くらいは意識して書くから
0897デフォルトの名無しさん
垢版 |
2022/05/09(月) 13:06:31.44ID:STAXlYzV
フィボナッチ数列イテレータでも同じだろう

fn fibonacci<T>() -> impl Iterator<Item=T>
where T: Clone + TryFrom<usize> + num::CheckedAdd,
{
let [zero, one] = [0, 1].map(|n| T::try_from(n).ok().unwrap());
itertools::unfold((zero, one), |(m, n)|
m.checked_add(&*n).map(|f| {
*m = n.clone();
*n = f.clone();
f
})
)
}

pub fn main() {
for f in fibonacci::<i8>() {
print!("{f} ");
}
println!();
}
0900デフォルトの名無しさん
垢版 |
2022/05/09(月) 14:10:19.70ID:MTI9nqyj
FizzBuzzの判定処理には Checked は不要
Overflowしないような列挙をするイテレータを実装する Checked が必要

という話だが、 >>817 でこういうイテレータの機能が突然持ち込まれたせいで、みんなが混乱したんやぞ
0901デフォルトの名無しさん
垢版 |
2022/05/09(月) 14:13:22.16ID:MTI9nqyj
>Overflowしないような列挙をするイテレータを実装する Checked が必要

「なら」が抜けてた
Overflowしないような列挙をするイテレータを実装するなら Checked が必要
0906デフォルトの名無しさん
垢版 |
2022/05/09(月) 15:48:28.09ID:ffvBu05T
プリミティブの整数型なら>>824みたいに0..=<T>::MAXでもいいし、
ジェネリックにやりたいなら0..=<T as num::Bounded>::max_value()もある

つーか自分が唯一の正解みたいなこと平気で言うそういうとこやぞ
0907デフォルトの名無しさん
垢版 |
2022/05/09(月) 15:54:04.25ID:RFFIBNHv
範囲とか順序とかはまた別の関心事だもんな
元々はせいぜい整数のfizzbuzz表現であって

>>906
そうそう
そういう感じよね
0910デフォルトの名無しさん
垢版 |
2022/05/09(月) 16:12:12.41ID:oybkhcFw
イテレータを返したいならイテレータアダプタとして実装すればいいだけ
FizzBuzzはイテレータのソースにすべきものじゃない
0911デフォルトの名無しさん
垢版 |
2022/05/09(月) 16:30:09.21ID:q8j6bWVf
>>906
checked_addの代わりにMAXやmax_valueを使うのは良くないです
checked_addは足し算の時に自動的に発生するオーバーフローを利用するため比較演算が発生しませんが
MAXやmax_valueはその値と比較する演算が余分に発生します
checked_addを使いましょう
0912デフォルトの名無しさん
垢版 |
2022/05/09(月) 17:00:00.27ID:Tvnmu5cO
>>896
何か腑に落ちたわ
多少なりともチーム開発の経験があれば
独りよがりなコードをドヤ顔でペタペタ貼り付けたりしないもんな
0915デフォルトの名無しさん
垢版 |
2022/05/09(月) 18:06:15.99ID:i/5F6ceJ
>>911
何を言っとるんじゃい
外から渡せばいいじゃんって話をしてるのわかってる?

fizzbuzzは100からのカウントダウンでやったって別にいいんだぞ

traitやenum使う前に関数の入出力考えなよ
0916デフォルトの名無しさん
垢版 |
2022/05/09(月) 18:09:52.19ID:MTI9nqyj
普通に考えたらこんなイテレータはstd::ops::Rangeとかで十分だし、しかもより高機能だから、自分で実装しなくていいよな
イテレータの勉強をしてるならともかくとして
0917デフォルトの名無しさん
垢版 |
2022/05/09(月) 18:29:52.00ID:V9K9H/9P
>>906
その<T as num::Bounded>::max_value()も一つの手であるが意外に致命的な欠陥がある
例えばBigIntなどの最大値がない型に対してBounded traitを実装できない
そして実際にBigIntではimplされていないため使えない

一方で<T as num::CheckedAdd>::checked_add()も同種の問題が起きないのか、だが
例えば最大値が存在しないBigIntでもCheckedAddはimplされている
オーバーフローが発生しないためNoneを返す必要がなく常にSomeを返す形となっている
つまり自分で作った型の場合であってもCheckedAddならば柔軟に対応できる

したがってRustで無限となりうる数列を扱う時はCheckedAddを使用することが好ましい
0918デフォルトの名無しさん
垢版 |
2022/05/09(月) 18:41:12.79ID:oo5VwkGP
impl FizzBuzz for T
vs
impl FizzBuzz for u8, u16, ...
の話だと思ってたんだが話が発散しすぎ
0919デフォルトの名無しさん
垢版 |
2022/05/09(月) 18:50:22.63ID:rGYbsi5m
>>915
>>918
FizzBuzzは単なる話の出発点の例の一つに過ぎなくて既に皆はもっと一般的な話をしているようにみえる
皆もFizzBuzz限定の話なんかに興味はなくて一般的な話に興味があるからではないかな
0921デフォルトの名無しさん
垢版 |
2022/05/09(月) 19:14:23.35ID:bdsCRHoE
>>920
各型には上限値(とその有無)がありメモリサイズとトレードオフだからそこは気を使うよ
Rustではrelease modeだとC/C++と全く同じでオーバーフローしてもpanicは発生せずに数値がラップしうる
例えばi32で2147483647に1を足すと普通の足し算の+つまりadd()だと結果は-2147483648となる
これは数値計算だけでなく単なるカウンター利用に至るまで深刻な結果を招きうる
そのため足し算ならばchecked_add()等を必要に応じて使い分けることになる
0922デフォルトの名無しさん
垢版 |
2022/05/09(月) 19:36:35.23ID:oo5VwkGP
>>919
impl Foo for T where クソ長制約
vs
impl Foo for 具体的な型
という話なら多少興味もってもらえるだろうか

impl Foo for T は基本的に避けるべきだと思う
0923デフォルトの名無しさん
垢版 |
2022/05/09(月) 19:43:08.06ID:K1S8Sh/L
>>922
Rust標準ライブラリでも他のクレートでもimpl Xxx for Tは山のようにある
それを避けるべきとの主張は全く意味不明
0924デフォルトの名無しさん
垢版 |
2022/05/09(月) 19:44:30.54ID:RFFIBNHv
>>918
> impl FizzBuzz for u8, u16, ...

これもう構文として取り込んだらいいのにな
impl_fizzbuzz(u8, u16, ...)
こういうのを書く文化をいっそ言語の構文に格上げして
0926デフォルトの名無しさん
垢版 |
2022/05/09(月) 19:48:56.84ID:iweuyBja
>>924
そういう型別impl列挙は主に基本的なTraitにおいて行われており
それらを組み合わせてTrait境界とする上位のTraitでは列挙せずfor Tで済むようにRustは上手く設計されている
0928デフォルトの名無しさん
垢版 |
2022/05/09(月) 19:58:12.86ID:oo5VwkGP
>>926
上位のtraitって例えばどういうもの?
それは本当にtraitにすべきものなの?
traitにすることでどういうメリットがあるの?
0929デフォルトの名無しさん
垢版 |
2022/05/09(月) 20:00:16.74ID:j+WTVljZ
おまえらの議論が唐突すぎてよくわからない
今日の議論の発端となった今朝の書き込み>>884と元コード>>817及びそれ以降のレスには
impl … for Tなんて話は全く出てきていないぞ
ちなみにコードは以下のようになっている

> fn fizzbuzz<T>() -> impl Iterator<Item=FizzBuzzResult<T>>
> where T: Copy + PartialEq + CheckedAdd + Rem<Output=T> + TryFrom<usize>,
> {
0930デフォルトの名無しさん
垢版 |
2022/05/09(月) 20:31:38.58ID:RYNyetIG
たぶんだけど>>922 >>924の話は
そのfn fizzbuzz<T>() where T: Boo + Foo + Wooとトレイト境界ジェネリックにしているのを禁止して
各々fn fizzbuzz_i8()、、、fn fizzbuzz_u128()を用意すべきという主張なんじゃないか
0932924
垢版 |
2022/05/09(月) 20:43:01.63ID:RFFIBNHv
>>930
言葉足らずでスマソ>>924で言いたかったことは

macro_rules! impl_foo {略} // 中でimpl Foo for
impl_foo!(u8, u16, ...);
今はマクロ使って↑こうなりがちなものを
いつか言語として↓こうなったらなぁという話
impl Foo for u8, u16, ... {略}

お分かりのとおり非常にしょうもない些細な話w
0933デフォルトの名無しさん
垢版 |
2022/05/09(月) 20:49:32.72ID:R+ViF9HF
>>931
その>>800のコードは特に問題が無いのではないか
強いて言えばその後に出たいくつかの改善案を反映して

impl<T> FizzBuzz for T
where T: Clone + PartialEq + TryFrom<usize> + Rem<Output=T>
{
fn fizzbuzz(&self) -> FizzBuzzResult<&Self> {
let [zero, three, five] = [0, 3, 5]
.map(|n| T::try_from(n).ok().unwrap());
match (self.clone() % three == zero.clone(), self.clone() % five == zero) {
(true, true) => FizzBuzzResult::FizzBuzz,
(true, _) => FizzBuzzResult::Fizz,
(_, true) => FizzBuzzResult::Buzz,
_ => FizzBuzzResult::Num(self),
}
}
}

こんな感じ?
0935デフォルトの名無しさん
垢版 |
2022/05/09(月) 21:41:03.35ID:uQhYdklw
>>922
これはそうだな
impl Foo for Tはstdに入れるくらいのよっぽど汎用的なものでもなければ避けるべき
0938デフォルトの名無しさん
垢版 |
2022/05/09(月) 21:56:24.70ID:ffvBu05T
impl<T> _ for T where T: ... 形式のことを blanket implementation って言うんですね
cargo doc で型のページの下の方に出てくるのは知ってたけど、正確な定義は今知った
0939デフォルトの名無しさん
垢版 |
2022/05/09(月) 22:01:11.13ID:jqMNiSw9
>>936
元々の質問がi32など各整数にメソッドを増やしたいとの質問だったようだ
それで>>789からずっと
trait FizzBuzz {
fn fizzbuzz(&self) -> FizzBuzzResult<&Self>;
}
となっていてそれを前提に皆が話をしてる

ちなみにコードがスレへ貼られていないと検索しても出て来ずに不便だとわかったw
0941デフォルトの名無しさん
垢版 |
2022/05/09(月) 22:53:43.92ID:noDNFQnc
>>940
そいつらは例えばイテレータメソッドを増やしたことすらない初心者かもな
Rustでメソッドを増やすにはトレイト定義が必須で欠かせない
0942デフォルトの名無しさん
垢版 |
2022/05/09(月) 23:21:10.68ID:ffvBu05T
そもそもメソッド増やす必要ありましたか?
仮に方法だけ質問されたとしても、「やめとけ」と答えるのも回答のひとつですよ
0944デフォルトの名無しさん
垢版 |
2022/05/09(月) 23:40:12.42ID:4G0/iQxJ
>>942
メソッドを増やすべき状況は多々あります
既に出ているイテレータメソッド等もその一例です
そして今回のFizzBuzzはあくまでも例ということですからFizzBuzz自体をメソッドにするべきか否かの議論はどうでもよく無意味でしょう
メソッド化を実現できること自体の方が本質にみえます
0945デフォルトの名無しさん
垢版 |
2022/05/09(月) 23:41:19.52ID:9vSL2/iz
>>942
最初の質問者 (>>781) はまだ Rust の基礎を学んでいる途中なのだというのが前提にある。
FizzBuzz についての質問であったとしても別に FizzBuzz を書きたいわけではなかろう。
Rust を学ぶ題材として試しに FizzBuzz を取り上げてるだけだ。
だから「FizzBuzz では」やめとけというだけでは回答として不十分。
「『必要であれば』書き方はこんな感じだよ」という形で話を膨らませるのはごく普通の対応に思える。
Rust 自体に習熟してないのにその上での設計の良し悪しなんてこの段階で論じるようなことでもない。
0946デフォルトの名無しさん
垢版 |
2022/05/09(月) 23:47:14.99ID:21Qt89Lm
>>942の人は単なる反抗期なんじゃね
書き込みを見ると何でも反対してる
それでいてCheckedAddを使わずにMAXを使え!など提案が的外れ
0951デフォルトの名無しさん
垢版 |
2022/05/10(火) 10:42:23.22ID:jQGJqYED
避けるべきというアンチパターンが出来ている時点で欠陥言語、 where T: Fooなどと書けるがRustは決してシンプルじゃない
0952デフォルトの名無しさん
垢版 |
2022/05/10(火) 10:47:34.92ID:7R870FiC
Rustの目標はシステムプログラミング言語だから、C/C++に比べてマシならおーけー
0954デフォルトの名無しさん
垢版 |
2022/05/10(火) 10:55:50.02ID:qByQ4KTB
     ,―彡 ⌒ ミ―、
    〈 〈| ´ん` |〉 〉
    \ ヽ _ / /
     /      /みんなで
     /      /ホモセックス
0959デフォルトの名無しさん
垢版 |
2022/05/10(火) 14:30:38.85ID:KWXviVB8
C言語でプログラミング入門した口だけどRustみたいな関数型言語わからなくて困ってる
例えばOCamlみたいな型推論前提で書かれているコードはどの変数がなんの型になるのかわからなくてつらい思いしている
関数型言語のプログラマはみんな自分で型を推論しながらプログラミングしてるんですか?
0960デフォルトの名無しさん
垢版 |
2022/05/10(火) 15:01:20.61ID:ZwDW7+At
>>959
むしろ型推論してくれるからプログラマーは楽
ただしどこかで歯止めがある方が安全安心確実だからRustでは関数の入出力のみ明示する
それも例えば>>929の返り値のように型そのものではなく抽象的にトレイト名で記述も可能

もしある値(式)の型を知りたかったらプログラムで表示も可能だけど一番簡単なのは
let a: i32 = 値;
とデタラメな型名i32を宣言してやるとコンパイラがエラーとして正しい型名を教えてくれる
0961デフォルトの名無しさん
垢版 |
2022/05/10(火) 15:32:07.15ID:7R870FiC
基本的にはIDEに型を教えてもらってたけど、慣れてくると自分でどんどん型がわかるようになる
0963はちみつ餃子 ◆8X2XSCHEME
垢版 |
2022/05/10(火) 16:07:49.23ID:dIEMLhL7
>>959
どの型に確定するのか把握しなければ使えないのだとしたら、その関数の設計が悪い。
まあ程度問題ではあるけど……。
0964デフォルトの名無しさん
垢版 |
2022/05/10(火) 18:09:35.29ID:KWXviVB8
>>960,962,963
ほーんなるほど
今ocaml勉強しているんだけど
if式のthen節とelse節の式の型は両方一致するとか、
match式においてもすべての分岐の式の型は一致するといかいったことを把握していってるわ
それ取っ掛かりにして関数全体の型把握するようにしたい
あと分岐の片方でラムダ抽象置いて束縛変数導入したらばもう一方の分岐ではconst関数に第一引数適用したの置いて分岐全体の型を合わせるとかいうテクニックとかも他人のソースから学んだンゴ
でも他の言語に比べてocamlのソースはなかなか転がっていない印象を受けるんごねえ
あとSKIコンビネータとかの型も式から推測するのもややこしくて難しいンゴねえ
0965デフォルトの名無しさん
垢版 |
2022/05/10(火) 20:54:08.50ID:ZAF82L15
rust-analyzerっていえばさ
俺のVSCodeをYoutuberのと見比べると、構文間違えなどのアンダーラインが出現・消滅するタイミングが違うんだよね
Youtuberらのがリアルタイムで線が引かれているのに対して、俺のは保存しないと線が引かれたり消えたりしない・・・・しかも、俺の手元ではMacでもWindowsでも一緒の症状・・・・
誰かエスパーさんいたら解決策を教えて!!!
0972デフォルトの名無しさん
垢版 |
2022/05/11(水) 16:47:09.56ID:0dtIdeQi
>>967
審査無しでユーザーが好きに登録できるパッケージマネージャにはよくありがちなことだな
パスワードが盗まれて正当なパッケージが置き換えられたわけじゃないからまだまし
Firefoxの拡張の中には第三者が権利を正当な形で引き継いだその後の更新でマルウェア化しているものがあるって報告があるくらいだし
0973デフォルトの名無しさん
垢版 |
2022/05/11(水) 21:53:53.62ID:8FoK4X2I
Rustで書くと依存crateが100オーバーになるのも珍しくないから
アプリ開発者がリリース単位で常時全部チェックするのは手間がかかりすぎる

全チェックじゃなければcargo crevとかで閾値決めとくとかしかないよね
0975デフォルトの名無しさん
垢版 |
2022/05/12(木) 03:17:07.69ID:NSKWr9J3
>>824
ホントだ
127の次でpanicした
(1_i8..).for_each(|n| print!("{n} "));
release modeではpanicではなく127の次が-128になって永久循環
0976デフォルトの名無しさん
垢版 |
2022/05/12(木) 07:30:29.11ID:mtqXpgib
適当に作れば溢れる前に止まる

fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: Clone + TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold((start, true), move |(n, is_first)| {
if *is_first {
*is_first = false;
Some(n.clone())
} else {
n.checked_add(&one)
.map(|new| {
*n = new.clone();
new
})
}
})
}

fn main() {
countup(1_i8).for_each(|n| print!("{n} "));
}
0977デフォルトの名無しさん
垢版 |
2022/05/12(木) 12:42:02.07ID:1TtHCqII
>>975
1_i8..=i8::MAXにすればいいだけ
型のMAX値までRangeFromでイテレートするなんて処理は現実のプログラムでは必要ないから
0983デフォルトの名無しさん
垢版 |
2022/05/12(木) 15:51:11.85ID:DUB7tBF0
>>980
Rangeはオーバーフローしないよね?
RangeFromでオーバーフローして困るなら上限を指定しないと

スレ立てもヨロ
0984デフォルトの名無しさん
垢版 |
2022/05/12(木) 16:26:15.18ID:nCP6t6gv
>>982
もっと厳しそうなStringで>>976をやってみた
Zの個数で数を表すZ

#[derive(Debug,Clone)]
struct Z(String);
impl std::fmt::Display for Z {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<usize> for Z {
fn from(n: usize) -> Self {
Z("Z".repeat(n))
}
}
impl std::ops::Add for Z {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Z(self.0.clone() + &(rhs.0))
}
}
impl num::CheckedAdd for Z {
fn checked_add(&self, rhs: &Self) -> Option<Self> {
Some(Z(self.0.clone() + &(rhs.0)))
}
}
fn main() {
countup(Z::from(1)).for_each(|n| println!("{n}"));
}

ちゃんと動作してZの数が増えて行くんだな
0985デフォルトの名無しさん
垢版 |
2022/05/12(木) 16:52:07.33ID:+mjBHcs3
>>984
それは独自の型であってStringではないよ
上限までイテレートするのに上限が無い型を実装して何がしたいのかわからないが
countup(Z::from(usize::MAX))とかで確認した?
0986デフォルトの名無しさん
垢版 |
2022/05/12(木) 16:58:46.77ID:lxDeZNmy
>>985
Rustのorphan ruleを知らないのかよ
独自の型に対してしか既存traitを実装できない規則なのでそこは独自の型で正しい
0988デフォルトの名無しさん
垢版 |
2022/05/12(木) 17:20:14.27ID:MHUEjPJH
>>984
“Z”を繰り返したいだけなら
(1..100).map(|n| “Z”.repeat(n))でいいのに
新しい型を作って4つも5つもトレイト実装することに何かメリットあるの?
0989デフォルトの名無しさん
垢版 |
2022/05/12(木) 17:27:09.04ID:x3l/UcP6
>>988
抽象的な考えが出来ない人なのかな
そういうのはあくまでも例であってZを表示したいわけではないことくらい分かるでしょ
0990デフォルトの名無しさん
垢版 |
2022/05/12(木) 17:46:52.13ID:yYN31ZGU
>>976
上限のある型を作ってトレイト境界を満たしてやるとちゃんと上限で止まるんだな

#[derive(Debug,Clone)]
struct FiveBits(usize);
impl FiveBits {
fn make(n: usize) -> Option<FiveBits> {
(n >> 5 == 0).then(|| FiveBits(n))
}
}
impl TryFrom<usize> for FiveBits {
type Error = &'static str;
fn try_from(n: usize) -> Result<Self, Self::Error> {
FiveBits::make(n).ok_or("overflow")
}
}
impl std::ops::Add for FiveBits {
type Output = Self;
fn add(self, rhs: Self) -> Self {
FiveBits::make(self.0 + rhs.0).unwrap()
}
}
impl num::CheckedAdd for FiveBits {
fn checked_add(&self, rhs: &Self) -> Option<Self> {
FiveBits::make(self.0 + rhs.0)
}
}
impl std::fmt::Display for FiveBits {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
0992デフォルトの名無しさん
垢版 |
2022/05/12(木) 17:57:40.16ID:W5nxdksy
>>985
それは君が思い込みで勘違いをしている
>>976のイテレータを見るとchecked_addが使われているため
その型に上限が有れば上限で止まるから君の言うとおり
しかしその型に上限が無ければ(リソースの有る限り)無限に進むことになる
0993デフォルトの名無しさん
垢版 |
2022/05/12(木) 18:12:51.67ID:evRfTR7c
>>789
> fn fizzbuzz(&self) -> FizzBuzzResult<&Self> {

その関数を使わせてもらってイテレータにしようと思ったら
参照を返しているために非Copy型に対して上手くいかなくて手詰まってしまった
10011001
垢版 |
Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 90日 14時間 44分 13秒
10021002
垢版 |
Over 1000Thread
5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。


───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────

会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。

▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/

▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php
レス数が1000を超えています。これ以上書き込みはできません。

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