21/08/24 22:59:11.03 972JwtmU.net
次スレは>>980が立ててくださいな
3:デフォルトの名無しさん
21/08/24 23:25:20.99 ELplZZUg.net
980ですゴメンナサイお詫びに
Rust The Book (日本語版)
URLリンク(doc.rust-jp.rs)
Rust edition guide (日本語版)
URLリンク(doc.rust-jp.rs)
Rust by example (日本語版)
URLリンク(doc.rust-jp.rs)
Rust cookbook (日本語版)
URLリンク(uma0317.github.io)
Rust API guideline (日本語版)
URLリンク(sinkuu.github.io)
Rust nomicon book (日本語版)
URLリンク(doc.rust-jp.rs)
Rust WASM book (日本語版)
URLリンク(moshg.github.io)
Rust embeded book (日本語版)
URLリンク(tomoyuki-nakabayashi.github.io)
Rust enbeded discovery (日本語版)
URLリンク(tomoyuki-nakabayashi.github.io)
4:デフォルトの名無しさん
21/08/24 23:38:41.54 dmSXpC2X.net
Rust CLI (Command Line Interface) apps Book
URLリンク(rust-cli.github.io)
Rust async-std Book
URLリンク(book.async.rs)
Rust The Unstable Book
URLリンク(doc.rust-lang.org)
Rust rustc Book
URLリンク(doc.rust-lang.org)
Rust Cargo Book
URLリンク(doc.rust-lang.org)
5:デフォルトの名無しさん
21/08/25 02:49:11.51 NhkykFBw.net
>>1
乙です。
6:デフォルトの名無しさん
21/08/25 03:59:04.43 4va1W6vx.net
The Rust Reference
URLリンク(doc.rust-lang.org)
The Rust Standard Library
URLリンク(doc.rust-lang.org)
7:デフォルトの名無しさん
21/08/25 08:19:23.75 o6V8MH2P.net
前スレで循環参照なんて初心者でもすぐ作れてしまうとの意見もあったけど
Rc型を使うだけの初心者には原理的に不可能
内部可変性を与えるRefCell型も併用しないと循環参照は作れない
一つの可変参照&mutか複数の不可変参照&のどちらかのみ許されるコンパイル時確認ルールを実行時確認ルールで行なうのがRefCell型
それにより明示的に可変参照を得ることで内部可変性を持てるようにしたもの
そしてRcと組み合わせてRc<RefCell<T>>を使うことで既にあるリンクを書き換え出来るようになりようやく循環参照を作れる
もちろん自分でunsafeすればやりたい放題てすがunsafeせずともメモリ安全性ルールの元に使えます
ここまで出来る人なら強参照Rcだけでなく弱参照Weakも併用できますから循環参照を避けることも出来るでしょう
8:デフォルトの名無しさん
21/08/25 08:36:39.57 cBrhi5Vz.net
マーフィーの法則
失敗する余地があるなら、失敗する
9:デフォルトの名無しさん
21/08/25 09:53:46.73 wz3i5qam.net
テンプレートがやたらたくさん入り乱れる言語は嫌いだわ
可読性めちゃくちゃ悪いよな
10:デフォルトの名無しさん
21/08/25 10:40:52.46 FDhW8k6p.net
>>7
そこまでできてやっとRust初心者という見方もあるかもしれない
11:デフォルトの名無しさん
21/08/25 11:24:43.65 cB4G1Ahy.net
直接関係ないけど、RefCellは借用チェックが実行時段階でのチェックになって
しまうんだってな。
12:デフォルトの名無しさん
21/08/25 11:34:25.36 N5SObJek.net
>>11
長文だから>>7をスルーしたな?
13:デフォルトの名無しさん
21/08/25 11:41:16.58 cB4G1Ahy.net
RefCellの借用チェックが実行段階にまで持ち越されるのは、循環参照とは全く別の話。
それはつまり、「ゼロコスト」ではないということ。
14:デフォルトの名無しさん
21/08/25 12:14:34.01 CoZuOKep.net
>>7
Rc<RefCell<T>>じゃなくてRefCell<Rc<T>>だね
気持ちはよく分かる
15:デフォルトの名無しさん
21/08/25 12:30:44.27 XsBK0uKE.net
>>14
どっちもあるけど通常はRc<RefCell<T>>だよ
16:デフォルトの名無しさん
21/08/25 13:42:20.13 6n+Di1sM.net
>>983
なるほどサンクス
リージョン理論に線形論理を上手く組み合わせて、cycloneとかの欠点を克服したrustってすげーなあ
とはいってもそもそも二重開放してエラーになるというのがピンとこない
free(a);
free(a);
は二重解放しているように見えて合法だろ?
一度目のfreeでaにNULLが代入されて、二度目のfreeでは引数がNULLの場合はそのままreturnって処理されるんだから、理論上は何度free使ってもエラーにならないじゃないか
17:デフォルトの名無しさん
21/08/25 13:42:36.69 6n+Di1sM.net
これに答えろ
18:デフォルトの名無しさん
21/08/25 14:22:27.47 aLlQE3on.net
>>16
なぜRustのスレに書いているのか不明だけど
当然NULLにならなかったよ
キャスト警告無視で
#include <stdlib.h>
main() {
char *ptr = malloc(1024);
printf("ptr(1): %x\n", ptr);
free(ptr);
printf("ptr(2): %x\n", ptr);
free(ptr);
printf("ptr(3): %x\n", ptr);
}
実行結果
ptr(1): ea8f72a0
ptr(2): ea8f72a0
free(): double free detected
core dump
19:デフォルトの名無しさん
21/08/25 14:49:12.37 FDhW8k6p.net
>>11
静的にチェックできないような使い方を実現するためのものなんだから
実行時チェックになるのは当然では
オーバーヘッドが気になるなら UnsafeCell を使えばよい
>>16
C には参照はないので free(a) という呼び出しで a の値が書き換わることはなく malloc で獲得した領域のアドレスがそのまま残る
領域自体は free で解放済みになっているため、アクセス (free 呼び出し含む) した場合何が起きるか分からない
このような解放済みの領域へのアクセスは use-after-free と言われるもので、脆弱性の原因として有名
20:デフォルトの名無しさん
21/08/25 14:50:41.52 6n+Di1sM.net
>>18
なるほど
free内で代入されるのではなく
自分で代入しないとNULLにはならないのですね。
ありがとうございました。
21:デフォルトの名無しさん
21/08/26 04:09:52.45 wR4WgiQO.net
そういやNull代入派とかいうのもいたな
22:デフォルトの名無しさん
21/08/26 07:18:01.38 BSY6c8/C.net
uaf防ぐのってぶっちゃけ簡単ですよね?freeしたあとにNULL代入するのを鉄則化するだけですよね?
23:デフォルトの名無しさん
21/08/26 07:18:53.92 tGDEA4MX.net
ポインタコピーすることないの?
加減算することないの?
24:デフォルトの名無しさん
21/08/26 07:42:26.49 YoD5H0JF.net
int* p1 = malloc(sizeof(int));
int* p2 = p1;
free(p1);
p1 = NULL;
free(p2);
極端に書くとこうかなあ?
25:デフォルトの名無しさん
21/08/26 08:58:05.69 yCq+tuyV.net
>>22
1つのオブジェクトを複数のポインタで挿している場合にそういうわけにはいかない。
26:デフォルトの名無しさん
21/08/26 09:21:56.64 yCq+tuyV.net
>>25
誤字訂正: 挿して ---> 指して
27:デフォルトの名無しさん
21/08/26 14:46:24.90 BSY6c8/C.net
>>25
複数のポインタにそれぞれNULL代入したらいいだけの話ですよね?
難しい話ですか?
28:デフォルトの名無しさん
21/08/26 14:52:56.47 BSY6c8/C.net
>>23
加減算考慮するとなんかやばいんですか?
本当に素人なので教えてください!!
29:デフォルトの名無しさん
21/08/26 14:53:33.93 BSY6c8/C.net
>>24
p2=NULL;すればいいだけの話ですよね?
30:デフォルトの名無しさん
21/08/26 14:54:04.18 ILFADcfC.net
Cスレでやれよ
31:デフォルトの名無しさん
21/08/26 14:55:34.47 s9ncfwmd.net
>>27
効率が落ちる。
32:デフォルトの名無しさん
21/08/26 15:01:32.05 jqKFKJA4.net
>>27
プログラミングをしたことがなく
頭の中での思考実験もできないのか
プログラマーに向いていない
33:デフォルトの名無しさん
21/08/26 15:04:39.60 s9ncfwmd.net
手で書くと効率は落ちないが、実行段階で自動的に NULL を入れようとすると
効率が落ちるという意味ね。時間とメモリーの両方で。
NULLが入っているか判定して error にするなどの処理も必要となったりする。
34:デフォルトの名無しさん
21/08/26 15:06:19.25 VJ7dcvV2.net
>>27
難しいです…
35:デフォルトの名無しさん
21/08/26 15:11:05.26 BSY6c8/C.net
>>32
すみません。
おっしゃるとおりかも知れないです。。
36:デフォルトの名無しさん
21/08/26 15:12:24.56 BSY6c8/C.net
>>31
>>33
そんなに効率が落ちますか?
37:デフォルトの名無しさん
21/08/26 15:18:41.61 s9ncfwmd.net
>>36
凄く落ちるわけではないが。
38:デフォルトの名無しさん
21/08/26 15:21:09.64 s9ncfwmd.net
>>36
参照カウンタ方式は、自動的に関連するポインタを巡ってNULLを入れるよりは
効率が良いのでプログラマーの裁量で選択できるようになっている。
しかし、それでも僅かに効率が落ちるのでなるべく使わないでプログラムする
方が良いと思うプログラマーが多いということだよ。
39:デフォルトの名無しさん
21/08/26 15:24:37.81 bKmDdfbf.net
プログラマーならば、まず思考実験、それで解決しなければコーディング
その上で問題点を尋ねる
それをしない人はプログラマーではないから、このスレの邪魔
40:デフォルトの名無しさん
21/08/26 15:24:45.61 BSY6c8/C.net
>>38
そんな僅かな効率の低下でも忌避されるんですね!!
わかりました!!
41:デフォルトの名無しさん
21/08/26 15:25:39.02 BSY6c8/C.net
>>39
こわい。。
42:デフォルトの名無しさん
21/08/26 15:25:45.57 s9ncfwmd.net
手作業で書く場合は、1つのオブジェクトを削除する場合、それを参照する
全てのポインタに NULL を入れるのは効率が良い。だから、多くのC/C++
プログラマはかつてそうしてきたし、今でもそうすることも多い。
ところが自動でそれをやるには静的解析は難しいので実行段階でも
余計なメモリーを追加で消費して行うことになる。それが効率が悪い。
そして、NULLが入っているかどうか分からないのでその参照を
使う場合には、いつも最初にNULLが入ってないことを確認してから
作業をする必要があり、その判定に 2 クロックくらいかかる。
この2クロックが忌避される。
43:デフォルトの名無しさん
21/08/26 15:26:04.39 pXAeL9Oq.net
>>7
言ってる事はかねがね同意ですが、プログラムが共同作業の為にRefCell<Rc<List>>とA氏が定義してあるものに
違う人B氏が何も考えずにRc::clone(&a)で循環を入れてしまう事は十分あり得るでしょう。
状況次第ですが循環参照を考慮してないA氏が悪いのか、Rc::clone(&a)でぶち込んだ人が悪いのかは要件次第ですが
これを簡単と言わずに(あなたは言っていませんが)難しいと表現するのは違和感がありますよ
44:デフォルトの名無しさん
21/08/26 15:28:09.24 BSY6c8/C.net
>>42
詳しい解説ありがとうございますm(_ _)m
メモさせていただきます。
45:デフォルトの名無しさん
21/08/26 15:28:30.66 uyKM6LSq.net
>>37
嘘を教えたらあかんやろ
N人の人が自分を指しているとして
まずそのN人をどうやって知る?
46:デフォルトの名無しさん
21/08/26 15:29:12.92 BSY6c8/C.net
>>45
自力で数えればいいんではないでしょうか?
47:デフォルトの名無しさん
21/08/26 15:30:36.47 s9ncfwmd.net
>>40
まあ、そういうこと。
というのは、参照カウンタも、1つのヒープノードに対して必ず1つ必要になるので、
ノード数が多いときには膨大なメモリーの無駄になるから。
それとノード数が多いときに参照カウンタを 0 クリアしたり、1足したり
する作業も馬鹿にならないと考えるプログラマが多い。
なぜかというと、そういう自動化を行わなくても、人が頭で考えて手作業で
NULLを入れても十分に安全にプログラムできるプログラマが多かったからだよ、
少なくとも昔のCプログラマには。
手作業でやってもとくに危険を感じないので、効率を落としてまで自動化する
必要が無いと思われている。
手作業でNULLを入れるのは難しくない。
ところが、コンパイラが自動で効率を落とさずにそれをやるのはめちゃくちゃ難しい。
それは人間の脳がそれだけ優秀だということだよ。
48:デフォルトの名無しさん
21/08/26 15:31:47.17 s9ncfwmd.net
>>45
手作業で人間が頭で考えたら、難しく感じないプログラマが多かった、という
ことだよ。
難しく感じるプログラマも居る。
数学の才能だと思う。
49:デフォルトの名無しさん
21/08/26 15:32:40.17 GoG5gW1P.net
コピーしたポインタを別スレッドに転送とかしてたら、いつNULL代入すべきかすら分からんしなぁ
50:デフォルトの名無しさん
21/08/26 15:32:44.57 s9ncfwmd.net
>>48
ああ、自動化の効率面の話か。
凄く効率が落ちるわけではないよ。
リンクで辿るだけだから。
51:デフォルトの名無しさん
21/08/26 15:42:17.45 Nkfv2brF.net
>>47
違うだろ
ある時点でNヶ所から指されているとして
そのNヶ所をどうやって知る?誰がどのようにNヶ所を管理する?
52:デフォルトの名無しさん
21/08/26 15:43:01.48 BSY6c8/C.net
>>51
僕がです。
53:デフォルトの名無しさん
21/08/26 15:46:08.68 s9ncfwmd.net
>>51
静的解析はコンパイラには難しいが、動的なら簡単。
人間にも、「一般性を持って」は分かる方法は無い。
54:デフォルトの名無しさん
21/08/26 15:47:35.53 s9ncfwmd.net
言っておくが現実世界では俺は天才だと言われているから、俺が簡単だと
思うことは、大部分のプログラマには難しいと思うかもしれないがな。
55:デフォルトの名無しさん
21/08/26 15:48:12.84 fifffju2.net
>>52
データ構造は入出力の変化に伴いどんどん変化していく可能性がありますから人間は覚え追いきれないよね
さらに一つのmalloc毎にそれぞれそこをポイントしている利用者の数も利用者数も異なりますよね
それらのデータをどこでどうやって管理するつもりですか?
56:デフォルトの名無しさん
21/08/26 15:54:12.28 BSY6c8/C.net
まず前提が誤りです
変化を追えば覚えられます
思考実験できないんですか?
57:デフォルトの名無しさん
21/08/26 16:04:38.88 xjpSGKrK.net
>>56
利用者リストを覚えておくためにメモリが必要やね
それもmallocするか
mallocで取ってきたメモリ管理のために更にmallocが必要となってしまったぞ
利用者が増えてきたら利用者リストの領域が足りなくなる
またmallocするか
全てにNULLを入れるためだけに大がかりになってきたな
この方法は本当に大丈夫なのか?
58:デフォルトの名無しさん
21/08/26 16:08:02.62 BSY6c8/C.net
>>57
静的に確認すればすむ話です
59:デフォルトの名無しさん
21/08/26 16:17:15.72 5iULk00o.net
データが育っていったら100か所からリンクされるとか普通によくあるわけだが
その100か所にNULLを代入しにいくために100か所の場所をリストで持つのか
しかもmallocした各データ毎にリストを持つのか
全てにNULL代入はあきらめた方がいいんじゃね?
60:デフォルトの名無しさん
21/08/26 16:20:01.23 4xBLfuks.net
アクセスするとたちまち例外発生するぬるぽにはどんなデータが格納されているのだろうか
61:デフォルトの名無しさん
21/08/26 16:23:55.37 YoD5H0JF.net
int* p1 = malloc(sizeof(int));
int* p2 = malloc(sizeof(int));
int* p3;
if (なんかの条件) p3 = p1; else p3 = p2;
free(p1);
p1 = NULL;
// p2はまだまだ使う
こういうときp3はどうするのかっていう
62:デフォルトの名無しさん
21/08/26 16:28:43.55 HI0uJlB9.net
すべてのヒープを**ptrで管理すればできなくもない気がする
参照するたびに有効かチェックしないといけないから激しく面倒だけど
63:デフォルトの名無しさん
21/08/26 16:29:37.04 BSY6c8/C.net
>>61
なるほど
参考になります
回答してくださってありがとうございました。
64:デフォルトの名無しさん
21/08/26 16:32:51.02 +fzqgCTs.net
>>62
その**ptrの格納領域の確保がデータ事に発生
しかも伸長してしまいますね
65:デフォルトの名無しさん
21/08/26 16:33:25.33 W3uKoL9G.net
何の参考だよ
66:デフォルトの名無しさん
21/08/26 16:36:08.26 YoD5H0JF.net
URLリンク(twitter.com)
最近はC++の発表資料を公開すると「Rustでいいじゃん」というコメントがたくさんつくのか…。Rustへの言及とか一文字も書いてないのに。
普及活動だと思うけど、さすがに嫌がらせチックに見える。
↓の資料公開した時の話っぽいんだけど、Rustでいいじゃんって言われてるソースが見つからない・・・
URLリンク(speakerdeck.com)
言われててもおかしくないとは思うけど、実際のところどうなんすかねえ
アロケータ回りがまだ弱いから少なくともゲームは10年後もC++のが強そう
(deleted an unsolicited ad)
67:デフォルトの名無しさん
21/08/26 16:38:42.43 n3k5ztC+.net
>>27
まだ利用者がいるのに全てへNULL代入しにいく時点で破綻
つまりまだ自分以外の誰かが利用中かどうかを知らないといけない
つまり利用者リストを管理する必要がある
68:デフォルトの名無しさん
21/08/26 16:39:16.76 6RYxqPIE.net
おまえらスレチがすぎるぞ
まとめてどっかいってくれ
69:デフォルトの名無しさん
21/08/26 16:43:10.20 xwYftXVU.net
>>66
Rust はメモリ安全性を保証することが論文で示されているので
どうしてもC++でないと出来ないこと(=まだRustが対応してないこと)であることを示さないと
「Rustでいいじゃん」となってしまうのは仕方ないかも
70:デフォルトの名無しさん
21/08/26 17:32:35.75 guyKB2RO.net
Rustは言語仕様が未確定なのが懸念事項かな
実用上は大して困らないからどうでもいいんだけど
期待してたRust Foundationは何故かディレクター探し始めてるしw
71:デフォルトの名無しさん
21/08/26 17:40:08.48 ek8X72OL.net
>>70
2018editionに2019のasync/awaitゼロコストサポートで言語としては完成でしょ?
72:デフォルトの名無しさん
21/08/26 17:48:35.66 TtF6fD9w.net
>>70
それを期待するならFoundationよりこっちかな
URLリンク(ferrous-systems.com)
2022年末にASIL-B認証が目標
73:デフォルトの名無しさん
21/08/26 18:01:26.94 BSY6c8/C.net
>>69
どの論文だよ
74:デフォルトの名無しさん
21/08/26 22:38:09.77 57cnJJ44.net
>>71
まだOpenなRFCいくつあると思ってるんだ
75:デフォルトの名無しさん
21/08/26 23:09:41.27 6XyucKpc.net
そんなこと言い出したら他の言語も未完成
永久にね
76:デフォルトの名無しさん
21/08/26 23:45:46.81 3VQCq3O/.net
でもSchemeとか言語仕様も形式意味論も定まってるし
77:デフォルトの名無しさん
21/08/26 23:50:11.85 guyKB2RO.net
とりあえず
URLリンク(doc.rust-lang.org)
のWarningを消してくれるだけでいいんだ
2018版だけでも確定できないのかな
78:デフォルトの名無しさん
21/08/26 23:57:00.95 yl47Ujhv.net
確定できないというよりメンテする人がいないんじゃないかな
言語仕様に詳しいけどコード書くよりドキュメント書きたいっていう奇特な人が要求されるわけで
79:デフォルトの名無しさん
21/08/27 00:00:45.70 cm2Md9qJ.net
ferroceneみたいに具体的な目標があって企業が投資してるなら進むだろうけど
リファレンスの更新とかあまり需要もないじゃない?
80:デフォルトの名無しさん
21/08/27 00:16:19.30 i+fGpSJz.net
完全な仕様書は間違いなく必要ではあるよな。
81:デフォルトの名無しさん
21/08/27 00:25:02.14 LvLZjQiD.net
完全な仕様書www
どんだけ素人なんw
82:デフォルトの名無しさん
21/08/27 00:25:46.96 vEj4Ie0t.net
第三者が処理系を作れるレベルで言語仕様が固まれば普及が進むと思うんだけどね
Rust Foundationにはそういう方向性を期待してたけど想像以上に何もしなかった
83:デフォルトの名無しさん
21/08/27 00:39:02.98 cm2Md9qJ.net
Foundationはもともと裏方に徹する組織だと言ってたし
その通りに動いているのでは
最近だとgccrsのライセンス絡みの知財チェックとかやってたかと
84:デフォルトの名無しさん
21/08/27 00:45:32.58 foV8RWB5.net
言語仕様が固まるってのは新機能の追加をやめるということ?
85:デフォルトの名無しさん
21/08/27 00:49:06.81 21t4GoG3.net
言語仕様とコンパイラのバージョンが一体化しているようではミッションクリティカルな領域で採用されない
86:デフォルトの名無しさん
21/08/27 01:13:55.67 vEj4Ie0t.net
>>84
厳密に運用するなら機能を追加するときは言語仕様のバージョンも上げる
固めるのは言語仕様の1つのバージョンってだけで言語の進化をとめるわけじゃないよ
87:デフォルトの名無しさん
21/08/27 01:28:41.09 i+fGpSJz.net
>>84
現状では「今そのように動いている処理系」と「処理系の (不十分な) ドキュメント」がある状態で、
それのどこからどこまでが言語仕様として満たすべき要件なのか保証されている動作なのかがわからない。
追加するも何も今の時点でどうなっているのかわからん。
どこかにはあったりもするんだろうけど、開発者向けの議論の中などに分散していて「仕様書」としてまとまってないんだ。
88:デフォルトの名無しさん
21/08/27 02:31:48.28 RPPiA5lc.net
安全性は型システムによるところが大きいから、仕様書が無いと使えないというのは無いと思うがね
89:デフォルトの名無しさん
21/08/27 02:39:18.77 8/O2Ek7n.net
コンパイラだってバグがない保証なんてないんだから
テストするしかないね
90:デフォルトの名無しさん
21/08/27 02:39:45.83 xRe29h0Q.net
ISO 26262のコンパイラ認証とか無理そう
91:デフォルトの名無しさん
21/08/27 07:59:32.64 ebhntqkF.net
LLVMの中間表現に依存してる時点で、言語仕様をまともに設定するのは無理。
だから他のコンパイラが作られることもない。
92:デフォルトの名無しさん
21/08/27 08:07:16.05 PnoFi7iU.net
仕様書、仕様書言っている人はOSやライブラリのAPIとかシステムコールとかはどう考えているんだろうね
MSDNだって盲信できるほどの信頼性はないし、OSS系なんてソースコードが仕様書状態だろ
もっと言えば処理系だってオプティマイザの仕様などは文書化されていなく、実際に調査しないと判らない事も多いよな
93:デフォルトの名無しさん
21/08/27 08:07:24.55 /EVH9JcP.net
こんな状態じゃc++の置き替えなんて夢のまた夢だな。
94:デフォルトの名無しさん
21/08/27 08:43:05.29 8HMvxqPN.net
完全な仕様書wがないのが問題だ思うなら使わなければいいだけ
クッソ無駄なやりとりでスレ消費すんな
95:デフォルトの名無しさん
21/08/27 08:54:32.00 ZVb7iGYH.net
少なくともC++はもっとずっと細かな仕様が書いてある。
例で説明する時でも、変な例で説明せずに数学の教科書の様な粒度の細かい例で
説明されているで、数学の教科書の様な雰囲気を持っている。
Rustの場合、ライフタイムの説明をとってみても、ちゃんとした数学的説明になってない。
96:デフォルトの名無しさん
21/08/27 08:57:07.99 ZVb7iGYH.net
時々プログラミングは文系でも出来るという人が居るが、そういう人には、
数学的な説明とは何かがぴんと来ないかもしれないので、良い仕様書も
書けないかもしれない。Rustのbookの著者ももしかしたらそうなのかも。
本人は頑張って書いているつもりでも数学的な論法になってない。
97:デフォルトの名無しさん
21/08/27 09:04:15.77 ZVb7iGYH.net
高校数学レベルで言えば、ベクトルの和の定義は図で例を使って説明されるが、
3つの矢印で、c = a + b が説明される。
これは最も粒度が細かい説明で、これ以上簡単に説明できない。
ところがRustのライフタイム注釈の説明は、説明に使われている例が不適切で
とても長いが本質が説明し切れてない。
本来は、「ライフタイム注釈とは何か」を数式や擬似命令などを使ってせいぜい2ページ以内で
説明できるはずだ。
ところが実際の説明は、変な例を使って長々と説明されている。
数学的な説明になっていないので応用が効かない。
数学的説明とはほとんどの場合「パターン」だ。パターンになっているから応用が効く。
パターンとして説明されてないと応用が効かない。
98:デフォルトの名無しさん
21/08/27 09:06:37.74 pCZxoLJn.net
コンパイラが一つしかない状況は現状メリットでしかない
C++のようなレガシー言語の轍を踏まない賢い選択
99:デフォルトの名無しさん
21/08/27 09:11:46.45 ZVb7iGYH.net
数学的説明にしたいなら、
「仮定」を置く。
「入力」と「出力」を明確にする。
「最も粒度の小さい例を書き、パターン」にする。
集合論や論理学の「かつ」「または」「積集合」「和集合」「背反集合」「区間の積」
などの言葉を使って書く。
ところが、Rustのbookはこのようなことが全く出来てない。
100:デフォルトの名無しさん
21/08/27 09:15:12.91 ZVb7iGYH.net
>>98
仕様書が数学的(パターン的、自動機械的)に書いてないので、厳密な
仕組みや仕様が分からず、他の人がコンパイラが作りにく。
だから、「Rustは実験してみないと分からない」。
ところが、CやC++やRuby,Java,C#,Pythonなどは実験しなくても分かる
ようになっている。それはなぜかというと、仕様が粒度が細かく説明されて
いるから、パターンになっており「パターンの一部への代入」や「当てはめ」
が出来るので頭の中だけで全てプログラミングできてしまうから。
101:デフォルトの名無しさん
21/08/27 09:17:17.15 X7Hfy4km.net
今日のNGIDがすぐ分かって助かった
感謝感謝
102:デフォルトの名無しさん
21/08/27 09:20:43.18 ZVb7iGYH.net
ちょっと難解だが高速なスクリプト言語としては使えるとは思う。
でもC++の置き換えは難しいな。
なぜならC++で出来ていたことがRustには移植できないから。
103:デフォルトの名無しさん
21/08/27 09:47:25.61 nKzWHFHq.net
算数がクラスで一番君がきてますね
104:デフォルトの名無しさん
21/08/27 10:21:55.10 EkQRESx5.net
なんやいつぞやのパターンマッチングの規格についてゴネてた子か
105:デフォルトの名無しさん
21/08/27 11:04:36.95 VpJ5g/uH.net
・Fortran/BASICからCへの移植は容易。単純なパターンが存在する。
アルゴリズムの変更は不要。
・C++からJavaやC#への移植は容易。単純なパターンが存在する。
アルゴリズムの変更は不要。
・C++からRustへの移植は困難。単純なパターンは存在せず。
アルゴリズムを根本的に変える必要がある場合がある。
106:デフォルトの名無しさん
21/08/27 11:10:56.79 ANmCg7EV.net
Rustアンチスレでやればいいのに
107:デフォルトの名無しさん
21/08/27 16:15:37.78 Ogrd1P9P.net
嫌なら使うなでおわり
現状嫌でも使うしかないくらいまでのシェア獲得してないし
108:デフォルトの名無しさん
21/08/27 16:28:39.42 i+fGpSJz.net
個人とし
109:ては使いたいけど組織として導入するには仕様の確実さというのは必要なんだわ。
110:デフォルトの名無しさん
21/08/27 16:36:16.05 +7PBhugx.net
C++ドロップアウターがOOPを学び直すには良いんでないの
111:デフォルトの名無しさん
21/08/27 16:44:56.69 2IayjhUe.net
大手IT企業たちの方針
プログラミング言語「Rust」のための「Rust Foundation」設立 -- AWS(Amazon)、Microsoft、Google、Mozilla、Huaweiが創設
URLリンク(japan.zdnet.com)
Facebookが「Rust Foundation」に参加
URLリンク(japan.zdnet.com)
112:デフォルトの名無しさん
21/08/27 16:56:21.47 e9EjTnUc.net
>>108
仕様の確実さってどういうの言ってる?
Rustでの具体例を1~2個あげてみて?
113:デフォルトの名無しさん
21/08/27 17:09:08.75 dNdDj0y1.net
>>111
lifetime関連
114:デフォルトの名無しさん
21/08/27 17:14:05.77 CxV5dN8D.net
>>112
関連じゃわかんねーわ
Lifetime Elisionとかは分かりやすく仕様定義されてるっしょ
115:デフォルトの名無しさん
21/08/27 17:44:50.51 i+fGpSJz.net
で、それはどこにあるっていうんだ。
これについての仕様はこっちに有ってあれについての仕様はあっちに有って
詳細はブログのここにあって……でもこれは議論のための暫定的なまとめで……
みたいなのじゃ組織の中で話を通せんのよ。
「Rust の仕様はこれです」「これを満たした処理系は (少なくとも今のところは) Rust と呼べます」
というのが仕様書であって、そういうのが欲しいわけよ。
116:デフォルトの名無しさん
21/08/27 17:53:04.46 n5KpIChT.net
その論法は流石に違和感が強い
GAFA級の組織(のどこか)では採択されるのにその組織では通らないというなら、その組織か説得者が外れ値なだけでは?
117:デフォルトの名無しさん
21/08/27 17:58:34.36 VUXc1RWG.net
老害さん 今日も公式読まずに 愚痴たれる
118:デフォルトの名無しさん
21/08/27 18:02:52.05 i+fGpSJz.net
>>115
そのレベルの大企業というのは策定側で関与しうるし
投機的な技術的投資にも貪欲だから
「大企業は動きが遅い」「稟議が厳密」という感覚ではない。
グーグルが大規模なサービスを開始からそれほど間を置かずに畳んだことなんて何度もあるだろう。
ぽんっとやって駄目だったらポイッと捨てられるんだよ。
119:デフォルトの名無しさん
21/08/27 18:09:32.26 34BhyfmP.net
そういう考え方ならISO標準でもできてから検討すればいいよ
時期尚早で時間の無駄
120:デフォルトの名無しさん
21/08/27 18:10:07.62 EkQRESx5.net
実際のところC++みたいに委員会とかが仕様がっちり決める言語ってどんくらいあるの?
そもそもC++だって仕様は決まってもコンパイラが微妙に準拠しきれてない気がするんだが
gccとclangは実用上困らんレベルだとは思うが
121:デフォルトの名無しさん
21/08/27 18:16:18.84 V38ET8xt.net
ISO標準のある言語で一番新しいのがRubyくらいか
もっと新しいのあったっけ?
やはりリリースから10年以上はかかる感じかね
122:デフォルトの名無しさん
21/08/27 18:18:18.61 i+fGpSJz.net
今の時点ではアーリーアダプタが使う言語なんだという立場でやってるならそれでもいいんだけど、
個別には割と (どこかには) まとまってるっぽいからもったいねーなという感覚がある。
123:デフォルトの名無しさん
21/08/27 18:27:08.06 zNEUYlcQ.net
お前が標準化委員会になるんだよ!
124:デフォルトの名無しさん
21/08/27 18:31:21.32 6epxU4jC.net
GAFAMだけでなく
日本でもNTTやTOYOTAなどもRustを採用しているわけで
まともな企業ならば支障なくRust採用を決定していってるでしょう
125:デフォルトの名無しさん
21/08/27 18:52:17.41 nKzWHFHq.net
特定の組織の土着信仰を一般論のように入れてもね
126:デフォルトの名無しさん
21/08/27 18:54:13.62 +wfLaYar.net
権威でものを判断したり
権威を借りて発言したり
頭ワリーわ
正気になれ
127:デフォルトの名無しさん
21/08/27 19:30:34.42 wbifwX7a.net
>>125
「権威に訴える論証」という人間の性質なんだよ。
けっこう効果あるから詐欺師とかマスゴミが良く使う。
128:デフォルトの名無しさん
21/08/27 19:32:40.90 +7PBhugx.net
あの松下もわが社の製品を採用しているんですよ~
情弱「ほほう、じゃうちも採用率するわ!」
129:デフォルトの名無しさん
21/08/27 19:33:38.34 ul1V6iOZ.net
メモリ開放の意味が解らない馬鹿に合わせるための言語なんだよな
馬鹿に合わせるとロクなことがない気がするんだけど
130:デフォルトの名無しさん
21/08/27 19:36:05.44 i+fGpSJz.net
わかってても間違えるのが人間なんだよ。
ヒューマンエラーを防止するのに「注意する」とかで対策を済ませちゃうわけ?
131:デフォルトの名無しさん
21/08/27 19:43:24.40 6epxU4jC.net
>グーグルによればAndroidに存在した深刻なセキュリティー脆弱性の70%近くがメモリー安全に関するバグに起因するという。
>同様にマイクロソフトも、同社製品に存在したセキュリティー脆弱性の70%がメモリー安全に関するバグに起因すると述べている。
>C/C++を使う限りセキュリティー脆弱性を根絶するのは不可能と考えて、Rustを採用するに至ったというわけだ。
URLリンク(xtech.nikkei.com)
132:デフォルトの名無しさん
21/08/27 19:45:18.24 +7PBhugx.net
あの会社もあそこもRust採用しているんだから絶対ヨシ!
URLリンク(i.imgur.com)
URLリンク(i.imgur.com)
133:デフォルトの名無しさん
21/08/27 19:48:14.38 +wfLaYar.net
C++で苦しんできた連中は
Rustのやろうとしたことは分かるし
例え失敗に終わっても責める気にはならん
どうころんでもしょせん死屍累々
Rustは人類の明日への尊い礎になるだけ
134:デフォルトの名無しさん
21/08/27 19:57:25.52 2e6D9xTm.net
>>125
そいつが権威主義的思考なのは確かなんだが
新興言語は大手の技術力ある会社がスポンサーにいて
継続的な投資が行われることが確実視されてるかどうかはすごく重要なこと
135:デフォルトの名無しさん
21/08/27 21:00:14.71 lzIWzz0k.net
>>123
二つともわけの分からん企業だな。
自動車と電話会社。
136:デフォルトの名無しさん
21/08/27 21:03:28.03 lzIWzz0k.net
人々の関心の高さは感じるけどな。twitterとか見てると。
137:デフォルトの名無しさん
21/08/27 21:07:48.98 lzIWzz0k.net
でもtwitterでは、Pythonも活況だし、KotlinもRustと似たり寄ったりの数、検索される。
なぜかQtやRailsは検索されにくい。Djangoは沢山検索される。
cplusplusは僅かに検索される。C++やC#は直接的にはそもそもtwitterでは検索できない。
Rustの話題性がPythonやKotlinやDjangoと比べて取り立てて多いということではないようだ。
138:デフォルトの名無しさん
21/08/27 21:44:01.80 pUsRfODL.net
The Bookは読まないくせにどうでもいいTwitter検索ばっかりしやがって
あーあのTwitterで独り言つぶやき続けてるひとだっけ?
忘れてた
139:デフォルトの名無しさん
21/08/27 21:51:00.96 6al70LN5.net
とにかく仕様が必要ならC++使えばよいのでは。主要メンバーがC++標準理解しているようなすごい人ばかりなんだろう
140:デフォルトの名無しさん
21/08/27 21:58:56.53 LFxFkvSL.net
>>138
自分達が「完全な仕様」と思えるものが存在することが重要視なんであって理解している必要はないんでしょ
ある種の宗教上の理由だよ
141:デフォルトの名無しさん
21/08/27 22:04:01.75 cMIVTei2.net
実際は、Rails : Laravel = 8:2。
Django は、0
どこの学校・サロンもほぼ、Ruby on Rails
142:デフォルトの名無しさん
21/08/27 23:00:14.26 n5qLAlq9.net
確実にinline展開する方法ってある?
手動で書く?
マクロだとどうにかなる?
143:デフォルトの名無しさん
21/08/27 23:01:33.75 81/NfoJ7.net
>>134 自動車の制御はわからんでもない 即応性と安全性の両立を図らなければならないのだから
145:デフォルトの名無しさん
21/08/27 23:13:16.52 EkQRESx5.net
#[inline(always)]でも100%ではないんだっけ?
146:デフォルトの名無しさん
21/08/27 23:22:31.27 i+fGpSJz.net
>>138
把握してないから必要なときにそれを調べればいいというようなまとまったものが必要なんだよ。
147:デフォルトの名無しさん
21/08/27 23:40:58.77 Q0/jYufH.net
Rust以外で高信頼性指向だとAdaとかMISRA Cとか?
148:デフォルトの名無しさん
21/08/27 23:45:38.03 8/O2Ek7n.net
>>143
実装はわからんけど、スペック的にはalwaysも飽くまでヒントらしい
149:デフォルトの名無しさん
21/08/27 23:52:40.05 8/O2Ek7n.net
>>145
MISRA Cは言語じゃなくてコーディング規約みたいなもん
組み込み以外では厳しくて準拠してられないと思う
150:デフォルトの名無しさん
21/08/28 00:02:42.33 sJf3n258.net
ファッション感覚のバカしかアピールしてない言語だわ。
c++理解してない奴がライフタイムをまともに理解できるとも思わん。
それもわからんバカがcをバインディングなんかしたら事故しか起きんわ。
安全性もクソもない。
151:デフォルトの名無しさん
21/08/28 00:03:44.74 7QeSIxjF.net
組み込み向けRustって1冊本が出たみたいだけど
実際のとこ、見込みありそうなの?
ただのホビー?
152:デフォルトの名無しさん
21/08/28 00:05:05.86 V8MBAFoh.net
>>148
C++ はわかっててもミスるんだってば。
153:デフォルトの名無しさん
21/08/28 01:13:09.37 d8vtmqNS.net
C/C++知らないと~と言う人には型理論知ってる?って聞きたくなる
コンパイルが通れば大体ちゃんと動くようになってるって感覚はhaskellとかOCaml寄りだと思う
154:デフォルトの名無しさん
21/08/28 01:30:02.36 V8MBAFoh.net
Haskell の型システムは好きなんだけど
さすがに副作用 (Haskell 的にはアクションだが……) の扱いがしんどすぎるし
元から C++ には慣れてるので C++ (というか C) 風な文法や意味論と
組み合わせた言語があったらいいなぁと思ってたので
Rust の台頭にはばんじゃーい ∩( ・ω・)∩
155:デフォルトの名無しさん
21/08/28 01:31:18.92 RscIlgzn.net
おまえらスルー力低すぎやろw
156:デフォルトの名無しさん
21/08/28 07:36:29.05 sJf3n258.net
>>151
お前こそ型理論知らんだろ。。
型理論てのは結局どれだけ簡易な計算でエラーチェックするかってだけの話なんだよ。
正しく示すだけならただ単に全実行するのが一番良い。
157:デフォルトの名無しさん
21/08/28 08:21:08.61 t8+wI51G.net
ガファムがファッションでプログラミングしてるとは知らなかった
158:デフォルトの名無しさん
21/08/28 08:46:20.33 YWpKrN9v.net
twitterでRustは話題性があるように見えるが、ためしにLISPやSchemeや
Clojure(言語)を検索してみてもRustと似たり寄ったりの書き込みがあった。
Haskelが次代を担う言語だ、的な書き込みすらある。
159:デフォルトの名無しさん
21/08/28 09:10:33.46 sJf3n258.net
今のgoogleじゃまともなc++プログラマもだいぶ減ってるわな。。
kumagiとかイキってるだけでまともに理解してねーじゃん。
160:デフォルトの名無しさん
21/08/28 10:14:03.36 M1lC0AeK.net
>>156
Haskellの型システムをRustは受け継ぎつつCG無しでメモリ安全性を達成しているので
Rustが実用的なプログラミング言語として現実に機能していますね
161:デフォルトの名無しさん
21/08/28 11:32:23.88 70jgR/1l.net
CG無し
162:デフォルトの名無しさん
21/08/28 11:39:53.86 mx2u+dFv.net
特撮オンリーでいくわけですねわかります
163:デフォルトの名無しさん
21/08/28 11:48:49.70 H94428G1.net
>>145
MISRAに従ってコーディングするの辛いぞ。
164:デフォルトの名無しさん
21/08/28 12:14:36.47 UcVwcAtV.net
>>160
特撮にはCG有るぞ
165:デフォルトの名無しさん
21/08/28 12:24:36.28 WeXzUgff.net
次のようなloop文のプログラ�
166:(可動)を while文やfor文に書き換えてわかりやすくしたいのですが 上手く値をbreakできないので助けてください fn main() { let a = [3, 5, 1, 6, 9, 4]; print_first_even_else_zero(&a); } fn print_first_even_else_zero(a: &[i32]) { let mut i = a.iter(); let even = loop { if let Some(&n) = i.next() { if n % 2 == 0 { break n; } } else { break 0; // not found } }; println!("{}", even); } 例えばwhile文なら let even = while let Some(&n) = i.next() { となりそうで さらに可能ならfor文で let even = for &n in a { となるかと思うのですが
167:デフォルトの名無しさん
21/08/28 12:44:34.41 t8+wI51G.net
let even = a.iter().find(|n| *n % 2 == 0).unwrap_or(&0);
168:デフォルトの名無しさん
21/08/28 13:03:12.27 WeXzUgff.net
>>164
当然それはわかりますが、for式やwhile式ではどうなるのか、という質問です
169:デフォルトの名無しさん
21/08/28 13:07:44.67 lHkfX/Au.net
前スレより
625 デフォルトの名無しさん 2021/08/16(月) 09:44:36.63 ID:MZWGbmHz
loop式はbreakで指定した値を返せるのに
なぜwhile式やfor式は値を返せないの?
Option型にしてbreakで値を指定した時だけSome(値)としてそれ以外はNoneとすれば便利なのに
630 デフォルトの名無しさん sage 2021/08/16(月) 14:32:54.40 ID:ebJKRLr3
手間かけて機能拡張するほどのメリットがないってことだろうね
URLリンク(github.com)
170:デフォルトの名無しさん
21/08/28 13:08:21.57 t8+wI51G.net
そうでしたかすみません
forとwhileは値を返さないのでご想像のようにはなりません
171:デフォルトの名無しさん
21/08/28 14:07:01.17 WeXzUgff.net
>>166
なるほど
そこでの議論を読むと一番の肝が、
「for式が()を返さないと、最後がfor式で終わる関数の返り値で互換性が無くなる」
というところにあるようですが
「break;」が()を返すことにすれば特に問題ないように見えます
実際にloop式で値なしのbreakだと()を返しています
つまり
・「for/while/loop式が返す型」は「break式の型」とする
・「値指定のない『break;』の型」は()とする
・「break式がない場合の型」も()とする
ここまでは現状と同じになりますね
問題はfor/while式はbreakせずともループを抜けるので、値を返すには、
・「『break 値;』があるfor/while式」は「else節を取ってbreak式と同じ型を返す」
という単純ルールだけで済むように見えます
何か見落としがあるでしょうか?
172:デフォルトの名無しさん
21/08/28 14:41:22.43 AMsYRDZ6.net
8日前にちょうどその内容で開かれたRFCあるじゃん
イテレータで思考停止してたわ
URLリンク(github.com)
173:デフォルトの名無しさん
21/08/28 15:14:25.46 WeXzUgff.net
>>169
なるほどありがとうございます
ところで現状のRustで>>163の例のloop式をfor式で行おうとすると
即時関数を使ってbreakをreturnに置き換えることで
let even = (|| {
for &n in a {
if n % 2 == 0 {
return n;
}
}
0
})();
と実現できることを思いつきましたが
この方法は表記コストはともかく実行コストもかかってしまいますか?
ちなみにこの「最初の偶数を見つけるコード」はあくまでも例として単純化したものを出しているだけで
実際には様々な例でこのパターン(=forやwhileで値を返せると便利)が出てくるので簡略な例題として話をしています
174:デフォルトの名無しさん
21/08/28 15:30:38.48 TLYe8gOd.net
>>168
イテレータのコードのほうが遥かにわかりやすい上に簡潔なので
新しく文法を拡張する価値がないと開発陣は考えてる点を見落としてる。る?
特にPythonの失敗例を鑑みれば機能追加される可能性は限りなくゼロ
175:デフォルトの名無しさん
21/08/28 15:43:20.61 M1lC0AeK.net
>>171
現実にはfindより複雑なことでも使うだろうし
async関数呼び出して判断もあるだろうし
イテレータでは無理なことも多いのでは?
176:デフォルトの名無しさん
21/08/28 16:01:24.35 Zz3t2OiP.net
Rustに限った話じゃないけど新しめの言語だとイテレータで記述可能な
ループは、出来るだけイテレータで記述するのが主流じゃね
forだのwhileはループ条件の誤りから簡単にバグが生まれるし
使わないで済むならそれに越したことはない
CやCの派生系言語がメインの人には理解しがたいかもしれないが
177:デフォルトの名無しさん
21/08/28 16:07:59.88 V8MBAFoh.net
C++ だとテンプレートの組み合わせで回すのも一般的だけど
Go だと凝ったことするよりなんでも愚直にループを回したほうがいいというのは
基本的なスタンスになってるよね。
178:デフォルトの名無しさん
21/08/28 16:18:39.14 TLYe8gOd.net
>>172
説得力のある実例を出せば今みたいにRFCが即closeされることはないんじゃない?
状況によってはイテレータを拡張したほうがいいという判断も有り得るし
今のforやwhileループみたいにmutで定義した変数を更新するのでも十分かもしれない
179:デフォルトの名無しさん
21/08/28 17:39:28.92 WeXzUgff.net
>>173
なるほど
出来るだけイテレータで記述する質問です
コマンドライン引数の数字の和をイテレータでpanicさせずに求める場合
これよりもっと短く出来ないでしょうか?
fn main() -> Result<(), std::num::ParseIntError> {
println!("Sum: {}", std::env::args().skip(1).map(|s| s.parse::<i32>()).collect::<Result<Vec<i32>,_>>()?.iter().sum::<i32>());
Ok(())
}
以下のように正しく実行できているのですがコードが長いのが気になっています
$ cargo run 10 20 30 40 50
Sum: 150
$ cargo run 10 20 XX 40 50
Error: ParseIntError { kind: InvalidDigit }
180:デフォルトの名無しさん
21/08/28 17:58:47.12 pl5LALbI.net
そんなに長い?
181:デフォルトの名無しさん
21/08/28 18:59:50.15 78cNf6mY.net
twitterで「Rust過激派がルール違反と判断された」
「CやC++のこと書いてた人にRustの話吹っかけて迷惑かけてた怖い人たち」
という話を見たが、誰の事?
どういうことなんだ?
182:デフォルトの名無しさん
21/08/28 19:21:11.03 0ROz2KLh.net
>>178
c++テンプレートテクニックの著者のことか?
183:デフォルトの名無しさん
21/08/28 19:24:41.12 0ROz2KLh.net
>>61
int* p1 = malloc(sizeof(int));
int* p2 = malloc(sizeof(int));
int* p3;
if (なんかの条件) p3 = p1; else p3 = p2;
free(p1);
p1 = NULL;
if (なんかの条件) p3 = NULL;
// p2はまだまだ使う
こうすればいいだけの話だろ?ガイジか?
このコードの後 p2またはp3どちらかをfreeしても二重開放にならんよ
このぐらいも考えられないのかガイジは(笑)
184:デフォルトの名無しさん
21/08/28 19:28:28.84 LR/RwLxP.net
いちいち差別的な用語を使わないとレスもできないのか
プログラマとしては一流なのかもしれないが、人間としては最低だな
185:デフォルトの名無しさん
21/08/28 20:41:09.02 WeXzUgff.net
>>177
このcollectしてから再びiterするところを何とか出来ないものかなと
println!("Sum: {}", std::env::args().skip(1).map(|s| s.parse::<i32>()).collect::<Result<Vec<i32>,_>>()?.iter().sum::<i32>());
イテレータだけを使う限界?
同じことをfor文を使うと短くなってわかりやすくなります
let mut total = 0;
for s in std::env::args().skip(1) {
total += s.parse::<i32>()?;
}
println!("Sum: {}", total);
186:デフォルトの名無しさん
21/08/28 21:00:48.99 t8+wI51G.net
std::env::args().skip(1).map(|s| s.parse::<i32>()).sum::<Result<i32, _>>()?
187:デフォルトの名無しさん
21/08/28 21:02:35.90 TLYe8gOd.net
ParseIntError返しても処理しないんだから
unwrap_or(0)みたいなので十分じゃないの?
fn main() {
let args = std::env::args().skip(1);
let sum: i32 = args.map(|s| s.parse().unwrap_or(0)).sum();
println!("Sum: {}", sum);
}
入力、計算、出力で分けてる
188:デフォルトの名無しさん
21/08/28 21:14:51.79 M1lC0AeK.net
>>184
非整数は飛ばす仕様になってる
エラーはエラーだと示すべきかな
あとエラー処理コードがないのは質問の本質じゃないからかと
189:デフォルトの名無しさん
21/08/28 21:23:19.42 AMsYRDZ6.net
println!("{}", std::env::args().skip().try_fold(|sum, s| Ok(sum + s.parse::<i32>()?))?);
try_fold使うと?演算子の入る場所が変わらずに済むっぽいな
190:デフォルトの名無しさん
21/08/28 21:24:03.32 WeXzUgff.net
>>183
なるほど!
sum()もcollect()のように様々な形の集積方法が指定できるのですね
i32整数一覧が入力に来るのにsum::<i32>()とi32型指定をしないと怒られた理由がようやくわかりました
sumとcollect以外にもそういう仕様のメソッドはありますか?
191:デフォルトの名無しさん
21/08/28 21:34:12.61 iw2Y3ERl.net
いちいち固有のiterator使うとか可読性悪くなるだけって場合も多い
192:デフォルトの名無しさん
21/08/28 21:54:20.22 WeXzUgff.net
>>186
素晴らしい!
少し修正して以下で上手く行きました
std::env::args().skip(1).try_fold(0, |sum, s| Ok(sum + s.parse::<i32>()?))?
fold()は知っていたのですがtry_fold()でOptionやResultの形でfold()できるとは便利ですね
ここまでまとめると
sum計算はResult型を返せるsum()があるので>>183でも行けて
このtry_fold()ならばsum計算以外にも汎用的に使えますね
193:デフォルトの名無しさん
21/08/28 22:01:27.46 TLYe8gOd.net
>>185
エラーだと示したいなら結果をハンドリングすればいいんじゃないの?
type Result<T> = std::result::Result<T, std::num::ParseIntError>;
fn main() {
let args = std::env::args().skip(1);
let sum: Result<i32> = args.map(|s| s.parse::<i32>()).sum();
match sum {
Ok(sum) => println!("Sum: {}", sum),
Err(e) => println!("Error: {}", e),
};
}
引数ゼロ個とかエラーは1種類じゃまかなえない
ハンドリングしたいならエラー設計がもう少し必要になるだろうね
194:デフォルトの名無しさん
21/08/28 22:12:53.29 M1lC0AeK.net
>>190
もちろんそんなことは皆わかっていて、最後のResultのErr処理は枝葉末節だから略して議論してるのだと思う
あとmain()でResult返してErrなら勝手にエラー表示してくれるみたいで便利
で、>>185で指摘したことは、>>184のunwrap_or(0)使用はエラーが消えるからマズいよね、ということでした
195:デフォルトの名無しさん
21/08/28 22:34:29.66 TLYe8gOd.net
>>191
何をそんなにカリカリしてるんだ?
main()でResult返したいなら別にそれでもいいんじゃない?
fn main() -> Result<()> {
let args = std::env::args().skip(1);
let sum: Result<i32> = args.map(|s| s.parse::<i32>()).sum();
println!("{}", sum?);
Ok(())
}
196:デフォルトの名無しさん
21/08/28 22:53:59.26 M1lC0AeK.net
>>192
皆がわかりきったことしか書いていなくて何をしたいのかわからないけど
Resultはエラー型も示さないとそのコードでは動かないよ
197:デフォルトの名無しさん
21/08/28 23:36:35.98 WeXzUgff.net
今回はargs部分も枝葉末節なので外してまとめ直すと
『数値と思われる文字列の配列が与えられた時に非数値があればエラーを返すとして』
let a = ["1", "3", "5", "7", "9"];
和の場合はmap()でResultのままsum()に渡してResultを返せる
let sum = a.iter().map(|s| s.parse::<i32>()).sum::<Result<i32, _>>()?;
和だけでなく積などもtry_fold()を使えばResultを返せる
let sum = a.iter().try_fold(0, |sum, s| Ok(sum + s.parse::<i32>()?))?;
let mul = a.iter().try_fold(1, |mul, s| Ok(mul * s.parse::<i32>()?))?;
今回はparse()で文字列→数値のResultだけど一般的にResultを返す関数なら応用可能
皆さんありがとうございました
198:デフォルトの名無しさん
21/08/29 09:06:24.35 CQyaTqyh.net
>>179
指摘している人も、加害者もエピステーメー氏とは全く関係ない人だと思う。
199:デフォルトの名無しさん
21/08/29 12:05:26.47 ehQ9raC/.net
>>195
えぴすめーてーじゃないほうの共著者のほうでしょ
200:デフォルトの名無しさん
21/08/29 13:31:13.01 pAl4bTqC.net
ローマ字で takaha... の人のことか。
Ukic...の人も何か言ってるんだけどどういう相関関係なのか。。
201:デフォルトの名無しさん
21/08/29 17:50:42.33 rRIESWs9.net
対立煽りに乗らないように
202:デフォルトの名無しさん
21/08/29 20:28:38.19 TMfqiUgQ.net
>>174
Goは確かにその方針だけど、イテレータというか高階関数を受ける型が総称では無いから.collectや.mapなんて
型ごとに定義しないと使えないから。Go2になってくれば違ってくると思う
一方でPythonだとfunctools.reduceなんかより、リスト内包表記が使われるのは局所性で速度が速いからだけど
ループで書かずにかなり長い表現をこれで書かれると保守しずらい。
Rustでもイテレータを何回も取り出してcollectしたり、foldしたりをドットで繋げられるのはあまり読み易いとは
言えないと思う。普通にiter()を何度も呼ぶのなら、let it = a.iter();して欲しい
203:デフォルトの名無しさん
21/08/29 21:26:36.38 FKMKprYN.net
そのitは一度しか使えないのでわ
204:デフォルトの名無しさん
21/08/29 21:37:15.37 3sJ97RgW.net
collect()したやつに.iter()は確かにやめてほしい
終端操作するなら何か変数に入れた上でやってほしい
205:デフォルトの名無しさん
21/08/29 21:56:31.67 Y4MENvlF.net
AdapterとConsumerは必ず分けろってこと?
もちろん分けたほうがいい場合もあるだろうけど
別に一緒でもいいと思うんだけどな
206:デフォルトの名無しさん
21/08/29 22:06:52.56 4xE/eKOX.net
>>201
中間変数を使うか否かだけの問題だからどうでもいい話
言語自体やその利用方法に本質的な問題があるわけではない
一方で>>199のGoの問題は深刻
Rustがトレイトで解決している分野だ
207:デフォルトの名無しさん
21/08/29 22:08:51.10 Y4MENvlF.net
上にあるコードでcollect()した後にiter()してるやつのことか
それなら分かる
208:デフォルトの名無しさん
21/08/29 22:19:15.00 FKMKprYN.net
あぁそういうこと
俺は別に繋がってていいかな
209:デフォルトの名無しさん
21/08/29 22:49:50.89 4xE/eKOX.net
>>204
それコードを改善したいという相談やんけ
しかも最終的には>>194のコードへと短くわかりやすくなったのだからRustはよく考えられてるなあとしか
210:デフォルトの名無しさん
21/08/29 23:12:51.30 Y4MENvlF.net
>>206
だからこそcollect()した後にiter()してるコードは改善したほうがいいよって話だろ?
211:デフォルトの名無しさん
21/08/29 23:54:47.37 6tO3Pyjl.net
和も積も求めたい時はどうすればいいかな?
文字列から数値への変換を二度するのを避けるとして
一つの方法はこのように一旦collectとして数値のVecを作ってしまう
fn main() -> Result<(), std::num::ParseIntError> {
let input_numbers: Vec<i32> = std::env::args().skip(1).map(|s| s.parse::<i32>()).collect::<Result<_,_>>()?;
println!("和: {}", input_numbers.iter().sum::<i32>());
println!("積: {}", input_numbers.iter().fold(1, |mul, n| mul * n));
Ok(())
}
それともcollectせずにイテレータのままで止めておいて使う?
212:デフォルトの名無しさん
21/08/29 23:59:56.40 53Xl0cl7.net
質問者とイライラ君が同一人物のパターン?
213:デフォルトの名無しさん
21/08/30 00:06:07.90 gpHI1J3P.net
product()使わないの?
214:デフォルトの名無しさん
21/08/30 00:06:33.11 kOjyqHoG.net
>>208
foldで和と差の2要素のタプルをとりまわせば良いだけ
215:デフォルトの名無しさん
21/08/30 00:56:00.83 5WtxtfY9.net
こうかな
println!("和: {}", std::env::args().skip(1).map(|s| s.parse::<i32>()).sum::<Result<i32,_>>()?
216:); println!("積: {}", std::env::args().skip(1).map(|s| s.parse::<i32>()).product::<Result<i32,_>>()?); println!("(和,積): {:?}", std::env::args().skip(1).try_fold((0, 1), |(sum, mul), s| { let n = s.parse::<i32>()?; Ok((sum + n, mul * n))})?);
217:デフォルトの名無しさん
21/08/30 01:17:16.84 XeeK64dt.net
>>209
っぽい
218:デフォルトの名無しさん
21/08/30 01:45:40.23 Fg1XXjYH.net
C++君も
219:デフォルトの名無しさん
21/08/30 05:11:39.37 1N5t7Emb.net
この前はNim連呼してた
220:デフォルトの名無しさん
21/08/30 05:23:26.66 YLwuWBBL.net
二重解放NULL荒らしもな
221:デフォルトの名無しさん
21/08/30 08:14:19.28 Bz8fsAkW.net
>>209
確かにこんな特徴的な勘違いをするやつが同時に二人出現するわけないわな
222:デフォルトの名無しさん
21/08/30 08:46:37.85 nNe2AEIB.net
じゃあワイはガリガリ君で
223:デフォルトの名無しさん
21/08/30 09:38:42.61 j0aQcfY/.net
>>214
C++ vs Rustスレでやれと何度言っても聞かずにここでイライラしてるよな
224:デフォルトの名無しさん
21/08/30 10:38:26.28 iy37Frot.net
上のイテレータ関連の質問に便乗ですが、
二次元vecの各要素をv[i][j]としたときに、
jごとの総和を計算するやつをイテレータできれいに書く方法ありますか?
例えばこういうやつです
let v = vec![vec![0; n]; m];
// (vの各要素を設定)
let mut result = vec![0; n];
for i in 0..m {
for j in 0..n {
result[j] += v[i][j];
}
}
225:デフォルトの名無しさん
21/08/30 10:46:23.34 qTeljjrO.net
>中間変数を使うか否かだけの問題だからどうでもいい話
Rustの場合、ライフタイムとオーナーシップの関係で
中間変数を使うか否かは結構重要な問題だったりする
226:デフォルトの名無しさん
21/08/30 10:56:01.57 b2fdtQYv.net
>>220
mapしてsumすればいいだけでは?
きれいかどうかは知らんけど
227:デフォルトの名無しさん
21/08/30 12:15:23.57 OrMFDzce.net
>>212
これ競プロ用でしょ
一般的なプログラミングとは観点が違うから最初に競プロ用だと書いておいたほうがいいぞ
228:デフォルトの名無しさん
21/08/30 12:35:22.36 iy37Frot.net
>>222
mapとsumで書けます?
iごとの総和なら単純に
v.into_iter().map(|v| v.into_iter().sum()).collect()
みたいな感じでいけるとおもうのですが、jごとだとちょっとわからないです
>>223
そうですね(実はもともとの発端は競プロではなかったりするのですが
229:デフォルトの名無しさん
21/08/30 13:18:46.38 cyaLRDjw.net
(0..n).map(|j| (0..m).map(|i| v[i][j]).sum()).collect()
2重forをの親子を逆転してイテレータメソッドチェーンに変換しただけという感じ
こんなことよりもっと意味のあることに頭使ったほうがいい
イテレータでとあったから上を書いたが現実にはndarray入れてsum_axis使うのがいいだろう
URLリンク(docs.rs)
230:デフォルトの名無しさん
21/08/30 13:30:16.69 w/2FJku9.net
こんなかんじかな
URLリンク(play.rust-lang.org)
231:デフォルトの名無しさん
21/08/30 13:33:43.06 w/2FJku9.net
ほぼかぶってたごめん
232:デフォルトの名無しさん
21/08/30 13:38:15.69 iy37Frot.net
>>225-226 インデックス自体のイテレータを作るって発想がありませんでした、ありがとうございます
競プロ用ではないしndarray使うのも考えてみます
233:デフォルトの名無しさん
21/08/30 14:45:34.31 07yK3Bti.net
汎用的には縦横入れ替えのtransposeを作っておけば色んな操作が楽かもね
イテレータ作成はサボってとりあえず関数版
fn transpose<T>(v: &Vec<Vec<T>>) -> Vec<Vec<T>> where T: Copy {
(0..v[0].len()).map(|j| v.into_iter().map(|vv| (*vv)[j]).collect::<Vec<T>>()).collect()
}
fn main() {
let v = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9], vec![10,11,12]];
let w = transpose(&v);
println!("{:?}", v); // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
println!("{:?}", w); // [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
}
234:デフォルトの名無しさん
21/08/30 20:06:03.21 kOjyqHoG.net
transposeみたいな関数用意すべきかは配列の要素数次第かなあ
たかだか1度しか読まないデータのためだけに配列全体をコピーするのはもったいないケースはありそう
235:デフォルトの名無しさん
21/08/30 20:10:57.31 kOjyqHoG.net
性能気にするなら Vec<Vec<_>> の形で数値格納するのではなく
Vec<_> に格納して (i, j) -> j*n+i みたいにインデックスを変換してくれるラッパーを被せた方がよさそう
236:デフォルトの名無しさん
21/08/30 20:40:55.84 W4wNS06G.net
>>231
それがndarrayなのでは?
237:デフォルトの名無しさん
21/08/30 20:50:30.90 k7vUdD10.net
これ匙投げたな
URLリンク(lkml.org)
238:デフォルトの名無しさん
21/08/30 21:09:01.34 bfTdIfIK.net
C++ドロップアウターの吹き溜まりスレ
239:デフォルトの名無しさん
21/08/30 21:16:46.70 Xk6FdWtE.net
>>223
競プロではむしろ回答時間や処理速度のほうが重要なので、
あえてこういうのをイテレータで実装しようとしないよ
おれなら間違いなくforで回す。わざわざイテレータで回そうと考える時間が無駄
だけど、後から振り返って、これをイテレータで1行で簡単に表示できるんじゃないかな?と思うことはよくあるんよ。
そして、ドキュメントを見返したり、他人のソースを見て、ああこういうやり方もあるんだなと学習する
競プロは実際のコーディングに役立たないという人もいるけど、
普段、自分が利用しないメソッドや方法を発見すること、実務で役立ちそうなアルゴリズムがあることを知る
という意味では意味があると思う
240:デフォルトの名無しさん
21/08/30 21:24:57.91 zvivEi6g.net
>>235
競プロに対する君の考えを急に述べられましても・・・
誰も興味ないよ
241:デフォルトの名無しさん
21/08/31 00:14:29.47 NYCNDL8F.net
>>236
逆にいうと、君が競プロはこういうものだろうという勝手な解釈で意見を言うことにも意味がないということよ
それこそ誰も興味がない
242:デフォルトの名無しさん
21/08/31 01:03:24.14 P5Wfb+Ix.net
今日もまたこのパターンw
ヤバいやつっすね
243:デフォルトの名無しさん
21/08/31 01:24:07.51 uga9Wpe3.net
たまにLKMLのURL貼られるけどURLだけ貼られてもなんもわからん
244:デフォルトの名無しさん
21/08/31 09:11:07.02 7zPv8PJ6.net
>>235
最適化まで考えるならforなんだろうけど、iterやcollectなんかが最適化が効かないのは今昔で、いずれは
最適化されるんじゃないだろうかと希望的観測を述べてみたり。実際gccなんかだとリンク時の最適化なんて
オプションあるし、あんまり凝ったiter/map/collect/foldだと理解に時間が掛かることはいなめない
245:デフォルトの名無しさん
21/08/31 09:16:05.39 uIcWKBVk.net
ぼくのかんがえた最強のコードが見下されたと思って悔しかったんだろうな
図星だったからこそ競プロでは逆にこんな書き方しないとか競プロは役に立つとか自己正当化に必死になる
追い越されたらバカにされたと思って煽り運転をする人と心理と同じなのでどちらの側も少し気を付けたほうがいい
246:デフォルトの名無しさん
21/08/31 10:02:54.76 Mir3UPzo.net
forよりイテレータのメソッドチェーンのほうが処理速度速かった気がするんだが
247:デフォルトの名無しさん
21/08/31 10:51:36.61 ajUm3fTo.net
やっていることが同じなら (最適化などによって) 結果のコードもおおよそ同じところに着地するよ。
248:デフォルトの名無しさん
21/08/31 12:44:14.75 Iv8lyMCD.net
C/C++でポインタを使うと速い(プラシーボ)
249:デフォルトの名無しさん
21/08/31 13:28:16.71 ajUm3fTo.net
せやな。 素朴なコンパイラならともかく
いまどきの最適化能力を期待できるなら
ポインタはエイリアス解析を困難にするから
むしろ足を引っ張る要素になる。
250:デフォルトの名無しさん
21/08/31 14:25:42.76 SlncBcTV.net
>>244
ポインタは適切に使えばデータ構造やアルゴリズム自体が根本的に変えることが
できるので使わない時と比べて計算オーダー自体が劇的に変化することがあり、
プラシーボではない。
Rustはその点でC/C++に勝てない事がある。
251:デフォルトの名無しさん
21/08/31 14:28:10.16 SlncBcTV.net
例えば、動的配列であるところのVectorはポインタでアクセスしても余り
効率は良くならないが、LinkedListは構造的にポインタで連結されており、
首尾一貫して添え字アクセスを使わずに必ずポインタでノードを識別する
ようにすれば、Vectorに比べて劇的に効率アップできることがある。
それはRustではほぼ不可能。ベンチマークはこの点が反映されてない。
252:デフォルトの名無しさん
21/08/31 15:24:34.70 8qO1h2Cp.net
続きはこちらで
スレリンク(tech板)
253:デフォルトの名無しさん
21/08/31 21:08:01.25 NYCNDL8F.net
>>240
最適化ではなくて、forを利用してindexで回さないとできないことが山ほどあるんだよね
例えば、二分探索や三分探索とか
foreach(a in vec)で順繰りに回せる処理ならいいけど、
そういう処理ではできないこともあるので、
forで回す前提で考えたほうが、あとから修正する余地があるので、どうしてもforでindexで回すことになる
これは、イテレータのほうがループが速いというのと、また別の問題
254:デフォルトの名無しさん
21/08/31 21:25:16.59 RnSwjxg3.net
rustのforは他言語でいうforeach(a in vec)やろ
255:デフォルトの名無しさん
21/08/31 21:26:56.02 RnSwjxg3.net
そもそも二分探索を普通forで実装しないだろ
256:デフォルトの名無しさん
21/08/31 21:39:55.47 KWeLtswn.net
for each 的なループで書いたものを二分探索に直す時点でプログラムとしては別物になりそうなんだけど
元のコードを iter じゃなく index アクセスするコードにしておくことでこの書き換えがどれほど楽になるのかね
まあここまでくると個人の好みの話なのでお好きにどうぞとしか言えないが
257:デフォルトの名無しさん
21/08/31 21:59:30.62 Gkdn/HXs.net
Rustのfor式を理解してなかったんかーいっ!!!
258:デフォルトの名無しさん
21/08/31 22:43:09.54 JHqwYLi1.net
>>250
それは違う
まず1点目
リスト対するfor文をforeachと書かずforと書く言語の方が非常に多く一般的
C++もJavaもJavaScriptもPythonもRubyもAwkもshもリストに対してfor文
次に2点目
Rustのfor文はIterator loopと明確に書かれてるようにリストや配列に対してではなくイテレータ正確にはIntoIteratorを実装するものに対して
259:デフォルトの名無しさん
21/08/31 23:30:53.76 lNvHqkvm.net
もうコイツどうにかしてくれwww
260:デフォルトの名無しさん
21/08/31 23:44:40.84 Gy6+Rq7
261:L.net
262:デフォルトの名無しさん
21/08/31 23:52:15.67 3ENBWRwS.net
調べたのにfor式を理解できんかったんかーいっ!!!
263:デフォルトの名無しさん
21/08/31 23:54:52.53 uga9Wpe3.net
Rustのforで二分探索ってどうやるのか気になる
264:デフォルトの名無しさん
21/08/31 23:56:09.61 cANa6qyq.net
どうせ自分で二分探索なんか実装しないだろ
気にするな
標準ライブラリ使え
265:デフォルトの名無しさん
21/09/01 01:38:57.54 iOouKnxp.net
>>258
for _ in 0..log2(n) as usize 的に回せばいいんでは?
まずやらないけど
266:デフォルトの名無しさん
21/09/01 01:59:11.36 p49DyIKy.net
>>260 それでどうやるかわかんねーんすけど
少なくとも>>249が言ってるforでindex回すってのとは違うような
267:デフォルトの名無しさん
21/09/01 03:29:00.40 MtyAaHfZ.net
>>254
もちろんRustのforはVecや配列に適用じゃなくてイテレータに適用
だからリスト処理しかできない言語のfor/foreachよりはRustのforは適用範囲が広い
しかし
>>258
for以前に確定しているデータしかイテレータ内で使えなくて
これはforの中で算出されたデータを借用規則によりイテレータに反映させられないためで
forの中でif分岐などする形で二分探索は無理と思う
しかし
元々の>>249が言う
「forを利用してindexで回さないとできないことが山ほどある。例えば二分探索とか」も間違い
このforはC言語などのfor (index初期値; index条件判定; index更新)を指しているが
二分探索はindex更新が状況により増減変化するためfor(;;)文を使えない
無理やりにforを使っても更新項がないため最初からwhile文を使うのが正解
つまりCでもRustでも同じでforではなくwhileが使われる
268:デフォルトの名無しさん
21/09/01 05:05:49.84 W5DSGMZK.net
こんな感じ?
fn binary_search<T>(array: &[T], target: T) -> Option<usize> where T: std::cmp::PartialOrd {
let mut left = 0;
let mut right = array.len() as i32 - 1;
while left <= right {
let mid = (left + right) / 2;
if array[mid as usize] == target {
return Some(mid as usize);
} else if array[mid as usize] < target {
left = mid + 1;
} else {
right = mid - 1;
}
}
return None;
}
Cで書いてもほぼ同じコードになるね
同じコードで任意の型に楽に対応できるRustの方が有利かな
269:デフォルトの名無しさん
21/09/01 08:56:44.94 wrwogreT.net
>>262
常識的なことを盛大に勘違いしてるので
>>254と同一人物なのモロバレだぞ
自分の書いたレスに他人のフリして間違いを指摘しようとするのは控えめに言っても病気
270:デフォルトの名無しさん
21/09/01 19:34:58.07 8EcW0Jj4.net
>>249
お、249は俺だ。
言われてみれば確かに二分探索でforはないなww
while max-min > 0 とかそんな感じだった。飲んで書いてたからすまんすまん
でも、イテレータでなくてindexでやるほうが便利なことのほうが多いのは事実なのよ
動的計画法で現在の参照している配列の前後の内容を参照する時とか
271:デフォルトの名無しさん
21/09/01 20:35:07.40 +RqlKI+M.net
indexが便利なことの "方が" 多いの?
indexが便利なこと "も" 多いならわかる
272:デフォルトの名無しさん
21/09/01 21:13:02.22 8EcW0Jj4.net
自分は競プロでRustを使ってるけど、その範囲では圧倒的にindex
273:デフォルトの名無しさん
21/09/01 21:38:57.15 8EcW0Jj4.net
うーん、こういうのはイテレータだけでもいけるね
URLリンク(atcoder.jp)
static mut tree_list: Vec<(i64, i64)> = Vec::new();
static mut job_list: Vec<(i64, i64)> = Vec::new();
static mut res_list: Vec<i64> = Vec::new();
fn main() {
unsafe {
input! {
edge: i64, job: i64,
tree_list0: [(i64, i64); edge-1],
job_list0: [(i64, i64); job],
}
tree_list = tree_list0;
job_list = job_list0;
res_list = vec![0_i64; edge as usize + 1];
unsafe fn calc(index: i64, count: i64) {
res_list[index as usize] += count;
for &(a, b) in &tree_list { if a == index { calc(b, count); } }
}
for &(a, b) in &job_list { calc(a, b); }
for i in 1..res_list.len() { print!("{} ", res_list[i]); }
println!();
}
}
274:デフォルトの名無しさん
21/09/02 00:21:53.48 nqohbFGX.net
ところで非同期ライブラリはどれが標準になるの?
275:デフォルトの名無しさん
21/09/02 01:42:02.99 S2XiqXH4.net
そりゃあれでしょ
276:デフォルトの名無しさん
21/09/02 11:37:50.37 UEpMLVw4.net
名前がダセェあれか
277:デフォルトの名無しさん
21/09/02 14:15:51.06 AObLO14s.net
お江戸
278:デフォルトの名無しさん
21/09/02 14:55:26.38 2FuyxSW6.net
>>269
futuresで行ける
279:デフォルトの名無しさん
21/09/02 15:18:41.35 l4XbE5cZ.net
Rustは、Tiobe index で、少し前に始めて20位に入ったが、今見たら
24位に下がってる。
このランキングの信憑性にも議論の余地はあろうが。
でも、日経の調査ではプロが使っている言語のTOPは、C/C++ということなので、
その調査とも整合はしている。
他の調査でも、CとC++を合算するとTOPか、2位になる。
280:デフォルトの名無しさん
21/09/02 15:28:38.88 l4XbE5cZ.net
URLリンク(www.rust-lang.org)
には、Rust公式サイト(?)で製品に使っている企業名が書いてあるが、
聞いたことが無い企業が多い。それはそういうものなのかもしれないが。
281:デフォルトの名無しさん
21/09/02 17:24:27.18 oZlwZEWk.net
>>254
お前の負けやでw
282:デフォルトの名無しさん
21/09/02 17:50:16.02 5ahReTWB.net
>>256
そらそろ宿題できたかい?
283:デフォルトの名無しさん
21/09/02 18:51:20.53 oZlwZEWk.net
>>277
お前の負けやでw
284:デフォルトの名無しさん
21/09/02 19:10:59.17 2FuyxSW6.net
また荒らしが来てるな
ところで非同期関数を呼ぶとfuture/promiseを返すだけでそのタイミングては実行開始しない怠惰タイプのプログラミング言語はRust以外に何があります?
285:デフォルトの名無しさん
21/09/02 19:14:26.82 rwq3+G7G.net
>>275
それはそう。
C++ を使ってる企業を並べてもほとんどは知らん企業になるはずだわ。
286:デフォルトの名無しさん
21/09/02 20:17:55.99 cdb/p6kF.net
>>279
イテレータも理解してないのに他スレでRustをバカ推しすんなよな
287:デフォルトの名無しさん
21/09/02 21:18:33.70 5ahReTWB.net
イテレータも理解してないアホがいるのか
288:デフォルトの名無しさん
21/09/02 21:26:15.36 +7Q9WvZy.net
>>282
ほぅ(for)( ^ω^)・・・
289:デフォルトの名無しさん
21/09/02 22:29:04.14 2FuyxSW6.net
>>269
せめてfutures::io::AsyncRead,AsyncWriteトレイトあたりで中立に互換性問題なんとかしてほしい
290:デフォルトの名無しさん
21/09/02 23:41:15.18 Ubg4tWaQ.net
>>268
これじゃナイーブ過ぎて通らないでしょ
291:デフォルトの名無しさん
21/09/03 00:54:23.74 2xSRfF9g.net
>>283
いちゃラブ ((っ´ω`)♡(´ω`⊂ )) すればすぐわかるのにね
292:デフォルトの名無しさん
21/09/03 13:54:25.02 j8ut1qUg.net
let a = [10, 20, 130, 40];
let v = vec!a;//←これってなんでダメなんですか?
293:デフォルトの名無しさん
21/09/03 14:17:04.75 9y+1HwQb.net
>>287
そういう構文規則(syntax)だから。
二行目は、vec! はマクロ名で、直後からはマクロの
294:引数列が続く。 そして、その引数列は決まった形式で書く必要があり、 vec!a という形式はそれに当てはまってない。
295:デフォルトの名無しさん
21/09/03 14:20:52.38 12Im1YVo.net
>>287
vec![]の[]は配列リテラルではなくて、一般的にマクロ呼び出しは[]か()か{}で引数を渡す
なので実はvec!(1)やvec!{1}も通るのだが、配列リテラルの見た目と合わせるために普通[]が使われる
296:デフォルトの名無しさん
21/09/03 14:26:18.39 j8ut1qUg.net
>>288
>>289
ありがとう
コンパイラの言い分もよくわかんなかったし、助かったぜ
297:デフォルトの名無しさん
21/09/03 15:36:22.40 eAcQJHwr.net
Cのvolatileって低レイヤで多用されるにもかかわらず実装依存なんだな
処理系依存の属性値的なのと同じようなもんか
Rustはcoreの中にvolatileアクセス用のメソッドが用意されている分進んでいる
298:デフォルトの名無しさん
21/09/03 15:55:22.52 4g+/rgm+.net
>>287
これは視点が斬新
いい質問だな
299:デフォルトの名無しさん
21/09/03 18:49:30.86 XJw5Azdc.net
何らか単純なmacroリライトとは異なるproprocessorが必要になりそうね
cとかlisp(cより遥かにまし)みたいなエラー挟み込むだけのマクロよりかは
rustのマクロはマシよね殆ど利便性は特になくcompile前にregex雑魚ver replace導入してるだけだけど
まぁ、素直なアプローチというか何というか(´・ω・`)
300:デフォルトの名無しさん
21/09/03 23:47:36.72 g/jq2Cau.net
rustの勉強のため自作のbashコマンドを、rustで書き直してるんですが、
コマンド置換( $(echo ) )はどうやればいいでしょうか?
Command::new('hoge').args......は調べたのですが、コマンド置換の方法が
どうしてもわかりません。
301:デフォルトの名無しさん
21/09/04 01:53:11.04 HZGHSQTb.net
>>294
Command::outputでstdout取得してきてそれをコマンド列に埋め込むとか?
302:デフォルトの名無しさん
21/09/04 05:20:01.42 iqtSb51S.net
インタプリタを作るのでなければ置換の必要性ある?
例えばこういうことが出来ればいいんだよね?
let s = format!("今日は{}曜日です", String::from_utf8(std::process::Command::new("date").arg("+%a").env("LANG", "ja_JP.utf8").output()?.stdout)?.trim_end());
303:デフォルトの名無しさん
21/09/04 09:57:53.03 KxfCnNFO.net
汚いコードだなぁ
304:デフォルトの名無しさん
21/09/04 12:45:59.97 mADKIhQi.net
>>294
rustで書き直すのにCommandは違くないか?
bashのランタイムでevalしてるだけじゃん
305:デフォルトの名無しさん
21/09/04 14:38:37.40 1i5Z4ndW.net
>>298
Command は system 関数相当じゃなくて fork/exec だから shell は関与しないと思ってたんだけど違うの?
306:デフォルトの名無しさん
21/09/04 17:05:10.13 iqtSb51S.net
>>297
美しいコードをご教示して下さい
307:デフォルトの名無しさん
21/09/04 17:33:46.64 mADKIhQi.net
>>299
fork/execだからとかそういう問題じゃなくて、
外部コマンド使うんだったら、それは単なるラッパーだろうと
要求する機能を満たすだけなら別にそれでも良いと思うが、
勉強のためにrustで書き直すというなら違和感がある
自作コマンドの内容にもよるけど
308:デフォルトの名無しさん
21/09/04 19:48:22.92 FwiYtexa.net
>>299
もちろんshellは関与していない。
環境変数PATHに従い直接起動。
>>301
どのプログラミング言語で書いていようが、外部コマンドの呼び出しは普通にある。
それをゼロにするかどうかは様々なコストの問題。
例えば、そこがボトルネックになったら内部化など。
309:デフォルトの名無しさん
21/09/04 20:41:42.28 HZGHSQTb.net
>>301
shell を作ってるんだから外部コマンド呼び出してなんぼだと思うんだが
310:デフォルトの名無しさん
21/09/04 21:53:33.09 CUdge0sZ.net
>>303
>>294 はシェルを自作してるの?
311:デフォルトの名無しさん
21/09/04 22:09:11.34 HZGHSQTb.net
>>304
自作のbashコマンドを自作の bash 互換シェルと読んでコマンド置換の仕組みを作ろうとしてるのかと思ったけど
もしかして bash スクリプトで書いたコマンドのことだったりする?
それにしたって外部コマンド含めて自作する必要はないと思うが
312:デフォルトの名無しさん
21/09/04 23:54:37.12 iqtSb51S.net
なるほど
>>296と書くのではRustで書き直したことになっていないとはそういう意味か
これでいいのかな
use locale::Time;
use chrono::{Local, Datelike};
let s = format!("今日は{}曜日です", Time::load_user_locale().unwrap().short_day_name(Local::now().date().weekday().num_days_from_sunday() as usize));
313:デフォルトの名無しさん
21/09/05 01:20:41.47 lJqHVJAL.net
$ foo=$(bar $(baz))
↓
let foo = bar(baz())
314:デフォルトの名無しさん
21/09/05 14:42:42.92 5vCe2TIK.net
>>294
>rustの勉強のため自作のbashコマンドを、rustで書き直し
URLリンク(github.com)
> コマンド置換( $(echo ) )はどうやればいいでしょうか?
URLリンク(www.joshmcguigan.com)
URLリンク(zenn.dev)
独自shellスクリプトをbashやzshのように実行する際は標準入力を逐次読むインタラクティブシェルの
動作モードの他に第一引数のスクリプトパスを受け取り連続的に動作するようにしなければなりません。
上記のサンプルのように変数やコマンド置換を展開(子プロを作って実行結果を保持する)パーサーが
必要になります。(上の例ではリダイレクトやパイプなどしか処理していませんが)またファイル先頭の
#!/bin/shと同じようにshebangを認識するのはOSが行います。
そのほかにもifに使われるや"["もしくはtestなどは大昔はコマンドでしたが、現在は多くのシェルでは
組み込みのビルトインコマンドになっています。
また現在でもbashなどでクラッシュさせる脆弱性が発見されていますが、GNU bashの場合はパーサーは
手書きではなく、parse.yなどのyaccです