Rust part9
■ このスレッドは過去ログ倉庫に格納されています
>>565-566
ありがとうございます。
無学なので少し書き方が分かりやすくなっても英語だとしんどい……。 ファイル (またはネットワーク) から得られる所定の書式のレコードの繰り返しを
イテレータとして抽象化したいと考えました。
(ちなみにレコードの繰り返しの前にレコードの個数を含むヘッダもあります。)
しかし IO はエラーの可能性があります。
書式の仕様に違反する入力になっている可能性もあります。
イテレータが返す型を Option<Result<要素の型,エラーの型>> としてしまうと
エラーの時点で終端という扱いにならないので様々なメソッドと組み合わせ難いですし、
Result を挟まないとエラーの内容を返せないのでハンドリングしづらいです。
何か綺麗にやれるイディオムのようなものがあったりしませんか? エラーの時点で終端にするかどうかは呼び出し側が決めることじゃない?
Option<Result<T, E>>もResult<Option<T>, E>もイディオムとしてよく使われてる >>569
出来るか出来ないかで言えば出来るし好きにすれば良い話ではあるんですが、
標準で良いされている様々なメソッド (たとえば map のような基本的なメソッドさえ!)
と「組み合わせ難い」ということが綺麗じゃないなぁという気持ちなんですが、
そこらへんの不格好さは許容するしかない雰囲気ということでしょうか?
(通常の終端に到達するのとは別に) 中断を表現する方法があって
中断の理由を伝播するのに便利な語彙を詰め込んだクレートがあったりすると
助かるんですが。 >>570
公式にあるイディオムっぽいのはこれとか。
https://doc.rust-lang.org/rust-by-example/error/iter_result.html
クレートは探すと色々見つかるけど、結局「便利な」ってのが人それぞれだし、あまり流行ってる感じはしないな。
むしろその中断表現をうまくやるアイデアがあるなら自分で作ったほうがいいのでは。 >>570
組み合わせ難いと言ってる内容をコードで示してくれないとなんとも イテレータとして抽象化したいってどういう意味なの
Iteratorをimplするってことなのかしら >>573
ここでいう「イテレータとして」というのは std::iter::Iterator に限るわけではなく、
繰り返しを表現する何らかの型定義と思ってください。
適当なクレートがあるならそれでいいですし、考え方だけでもいいです。
欲しい機能をあらためてまとめると
・ 繰り返しに (終端に到達する以外の) 中断の方法が用意されている
・ 中断したときに中断の理由 (エラー型の値) を伝える方法がある
なのですが、
std::iter::Iterator だと next が返す Option<Result<T, E>> でエラーのときに
「中断」しようとすると for 文の中で break する書き方くらいしか思いつかず、
自分で便利なものを作ろうにもどう作れば便利になるのかも
想像がつかないのです。 >>574
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=aaf882f54a7b6330ee6ad2106be92717
こんな感じでscan使えばNoneを返したところで
イテレーションを中断できるしErrの値も列挙できる 中断するだけなら take_while 使うという手もある 俺もtake_whileを思い浮かべたけど関数を作るわけじゃないんでしょ
ゴールがいまいちみえないからイメージでいいのでコードで用件を示してほしい 単にエラー返して中断したいだけならResultにcollectしたりtry_for_eachで消費すればいいよ
イテレータアダプターとしてエラーも含めて列挙しつつ次につなげたいなら>>575が書いてるscanやtake_while系
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=113dcf689b4d941c89e714ebb1414958 AsRefトレイト使ってenumから&str返すのっておかしい?
Display実装で文字返してたらアロケートされるからAsRef使おうと思ってるんだけど >>579
AsRef に拘らず独立した as_str 用意した方が良いと思う AsPath が AsRef<Path> になった過去もあるから汎用性持たしてas_str実装するよりAsRefで実装する方がいいといいと思うけど他の人はどう思う? 自分で使う、as_str
ライブラリとして他で使われる、AsRef >>580
学習難度はまず低級言語と高級言語両方の利点欠点を理解しないと良さが理解出来ないからねえ…
設計思想からして中上級者向けだから仕方ないかも 単に学習難易度が高いだけでなく、学習が済んだ後もこの言語はめんどくさいが、
C++よりもむしろ。 >>582
AsRefはIntoOwnedと対になっていて str<->String Path<->PathBuf みたいな ref/owned 関係にあるもの同士の変換に使うものだと思う
enum -> &str はそういう関係にはないので微妙に思う >>586
風俗で事が済んだ後で説教始めるオッサンみたい C++とRustで難しさめんどくささの方向性違うしな
好みの範疇だと思ってる Rustのめんどくさいところはダントツでクレート関係だよな
標準で入ってないかつ、細かすぎるからコンパイル糞長いし、APIの仕様が統一されてないからドキュメント見ないと話にならんとこ
しかもクレートによっちゃライフタイム絡ませてきてめちゃくちゃになるし
C++はとにかく言語仕様のいらない豊富さが嫌気さす >>590
traitのおかげで他と比べるとAPIの統一性は達成されてるようにおもう クレートいいと思うけどな
標準ライブラリに入れると破壊的変更できなくなるけどクレートなら古いバージョン使うことも出来るから
気兼ねなくライブラリを進化させることが出来る pure-Rustのクレートなら今のところ確実にコンパイルは通るしな。
C++だとGitHubから拾ってきたライブラリが手元でコンパイル通るかどうか半々って感じで厳しい。
マイナーなディストリビューションのせいではあるけど、全部Ubuntuに統一というわけにもいかんしなぁ。 struct A;
struct A();
これとこれが定義できる理由ってなんかある?
struct A {};
だけで済むし、記述バラバラになるから統一したいんだけど Rustが一番めんどくさいのはメモリ管理だな。
というよりメモリ管理の事ばかり気にしてプログラムしなくてはならない。
plain CやC++ではそこまで気にしなくて良い。 結局メモリを気にする言語にへんな暗黙性を入れるのは失敗ってことだな。 Rust で書いたツールにドキュメントを付けようとしています。
ライブラリのドキュメントではなくツールとしての使い方の詳細で、
readme に書くには大きすぎるような文章です。
cargo.toml では package.documentation でドキュメントの場所を URL で
示すことは出来るようですが、パッケージ内にドキュメントを一緒に入れておいて
cargo install で適当なところにインストールするようなことは出来ないのでしょうか?
あるいは cargo の直接の管理下には入れられないにしても
なんらかの習慣があったりしますか? manみたいにドキュメントインストールする方法は知らないな。
ローカルにインストールしなくてもリポジトリのwikiあたりに使い方書いておいてそれ見てねでいいんじゃないかとおもうけど。 ビルドスクリプト使ってenv::var("OUT_DIR”)で取得できるパスにファイル出力してるのが多いみたい なるほど。 そういうやり方もあるんですね。
でもドキュメントを各環境で適切な場所に
インストールするのは結局は手作業ということになりそうですね。
そういうことなら無理に自動化するのは諦めて
必要ならこのディレクトリで mdbook コマンドを実行してねみたいな感じにした方がかえって楽かな…… cargo installでrustバイナリ以外をインストールするオフィシャルの方法は長年用意されてないから別の手段で頑張るしかない
https://github.com/rust-lang/cargo/issues/2729 fn num() -> usize {
10.pow(9)
}
この定数はなぜ推論でusizeにならないんですか? なんでいちいちゴミをワサワサDLしなきゃならねーんだよゴミ言語 DustじゃなくRustだからゴミじゃなくてサビ言語だよ その2つは別のもの
どっちも存在する
&strはstring sliceのborrow
&StringはStringのborrow >>613
同一だと思ってたけど違うの??
&strを要求する関数とかメソッドに&String渡しても動くもんだからてっきり &strはStringの一部か全部へ参照 rust的にはスライスへの参照
&string[1..3] こういうこと
引数を&StringにするのStringの参照しか渡せないが、&strにすればStringの一部や””で囲った&strも渡せる >>614
引数として&strをとるメソッドや関数に&Stringは渡せないんじゃなかったっけ
self の場合の話? >>618
二つ目の例だけ記憶してて勘違いしてたみたい。ありがとう
>>619
rustは暗黙変換かなり少ないからマシな方だと思う
メソッドのselfの暗黙変換はないとつらいかと Option::filterのResult版って無いのかな? >>621
条件に合致しない場合は何を返して欲しいの? >>622
引数で渡したエラー値をErrにくるんで返してほしい >>623
うん、それが最適でしたね
もともとTと&T -> boolからOption<T>を構築してたコードがあってSome(t).filter(|t| !t.is_hoge())ってしてたんだけど
それをResultに変えようとしたらif式で数行増えちゃって
ちょうど対応するようなのって無いのかな?って思って質問した次第でした それはok_orかok_or_elseで変換すればいいだけじゃなくて? Rustの良さが実感できるのは長大なコードをチーム開発するときなのかな
小さいプロジェクトならRustは
・生ポインタ使わない
・できる限りSTLを使う
・const、moveをデフォルトで使う
ことにしたC++に敵わないような
C++の方が柔軟だしず〜っと短く書けるし あ、標準の機能とかイディオムを巧みに使えばC++並みに短く書けるよ、というのがあったら教えてください どちらかというとC++の方が長くない?
ヘッダとソースの重複とかイテレータが冗長とかshared_ptrが長いとか。
あと小さいプロジェクトだとビルド環境構築の手間が
相対的に大きくなるからC++はつらいな。 あとなるべくconstにしたいのに多用すると結構長い RustスレなのでRustの味方をすれば良いと思うが、>>629はあまりにも言いがかりだろう
> ヘッダとソースの重複
重複するコードを書かなければならないことなどない
> イテレータが冗長
今どきautoせずにイテレータを書くことはない
> shared_ptrが長いとか
これは確かに >>631
テンプレートでなければ関数プロトタイプと実装で同じこと書くと思うんだけど最近は違うんだっけ?
あとイテレータはbegin/endのこと。これも書かなくて良くなったりしてる? >>632
特殊化が必要なら当然特殊化するし、プロトタイプしか与えられてない関数は当然中身を他の場所で実装しなければならない
が、いずれもヘッダその他で書いてあるのと同じことを繰り返し書くという意味ではない
「引数と返り値をプロトタイプと実装で二度書くじゃないか」と主張してるのか?
だとしたら、「Rustのtraitとimplは同じことの繰り返しだ」と同レベルのデタラメだ
> あとイテレータはbegin/endのこと
範囲for文はあるので、コンテナを走査する時にはbegin()もend()も書く必要はない
が、begin()やend()の指すイテレータが必要なら当然書く必要がある
しかしこれより簡潔な表現方法があるか? >>633
いや、Rustのtraitとimplも同じことの繰り返しだと思うが。
もちろんそれぞれに意味があるのは分かるが、今話題になってるのは長いかどうかなので、単に長いのでは?ということ。
begin/endは言われてみれば確かにそんなに長くもないな。 そういえばRustだとderiveで導出できるようなのを
手で書かないといけないのも面倒だと思ってたけど
それも最近のC++だと便利になってるのかな? >>634
〜〜〜〜〜ッッ!!?!!????
型を示すだけぞ???
どういう理屈で「どちらかというとC++の方が長い」???
「プロトタイプ」なる仕様が冗長だと思ってるということか?
だとしてもどこがどうRustより長い?
traitとimplが同じことの繰り返しに見えるなら尚更 ゆうてID:tj1CufyMがもの知らん過ぎるよ
刃牙クンが正しい >>627 がどういうところでrustを冗長に感じたのかが分からないと身のある議論にならないのではないか let v2 = v.iter().take_while(pred).collect::<Vec<_>>();
auto iter_end = std::find_if_not(v.cbegin(), v.cend(), pred);
auto v2 = std::vector<Hoge>(v.cbegin(), iter_end); Rust言語を推進する「Rust Foundation」設立。AWS、Google、マイクロソフト、モジラ、ファーウェイらが設立メンバー
https://www.publickey1.jp/blog/21/rustrust_foundationawsgoogle.html >>646
無難なのは tokio だが、言語としては非同期ランタイムを固定しないという明確な指針がある以上は
使い分けしなさいということになると思う。 traitとimplが同じことの繰り返しは流石にキテレツ過ぎてワロタ
こういう基本的な言語仕様も分かってない人にとってRust使うメリットってあるのかな
「どっちが短く書けるか」については、流石にC++じゃないかな
良くも悪くも自由だし、短さだけを追求したクソコードも作れる
一方でRustも一応エルゴノミクスを掲げてはいるし、冗長さは感じない
C++が短くでき過ぎる、って言い方が正しいとおも >>642
林檎やfacebookの参入、ゲームやスマホでの導入例が出てくればこれはかなりの地位を占めるな コードを短くできるなんてどうでもいいことに囚われて半端になってる印象。 Firefoxでは160,000行のC ++コードを85,000行のRustコードに置き換えたと言ってる いやーRust難しくないっすか…
3回くらい入門したけどrustlingsのiterあたりでつらくなってくる
アホは他の優しい最新言語やったほうがいいんですかねぇ でもRustのコンパイル基盤のLLVMはいつまで経ってもC++製のまんまだよね
書き直さなきゃC++の牙城は壊せんで craneliftがあるじゃん
デバッグビルド向けだけど コンパイラはrust自身で作られてるからそのうちそうなるんじゃね? >>658
Appleは重要なパトロンではあるけど関心はApple以外誰も興味無い
キメラ言語のObjective-Cを守る一点だけだろ >>657
というかC++をちゃんと使いこなしている人は、Rustが便利だとは思えない人が多い
のでRust化する動機が無い。 >>662
>>627てこと?
> 小さいプロジェクトならRustは
> ・生ポインタ使わない
> ・できる限りSTLを使う
> ・const、moveをデフォルトで使う
> ことにしたC++に敵わないような
> C++の方が柔軟だしず〜っと短く書けるし >>663
むしろ、STLがクソすぎるのがC++が嫌われる原因。
C++は、STLを使わずに独自templateライブラリを使うのが便利。 >>664
「使いこなす」がレベチ過ぎてワロシ
コンテナとアルゴに関しては俺もSTL使う方が良いと思ってたわ
vector<bool>とか、難のある仕様があるのは理解してたがそういうのに個別に対処すれば十分だろうと
リーナスとかもSTLが大ッ嫌いだという記事をよく見るが、具体的にどこを毛嫌いしてるのか俺は理解していない ■ このスレッドは過去ログ倉庫に格納されています