X



Rust part9
■ このスレッドは過去ログ倉庫に格納されています
0212デフォルトの名無しさん
垢版 |
2020/09/25(金) 01:43:09.63ID:rqLAnW3Q
C++系言語に見た目を近づけるという設計意図があるから()を明記するという判断にはならなかっただろうとおもう
0213デフォルトの名無しさん
垢版 |
2020/09/25(金) 06:33:09.44ID:JNOcuagu
戻り値型の宣言にも -> () っていちいち書かなくていいしなあ
そういうもんだとしか
0215デフォルトの名無しさん
垢版 |
2020/09/25(金) 07:33:16.25ID:SbSfhD0k
単純に、セミコロンの有無だけで区別するのが視認性が良くないんだよな。
エディタの方で違いを目立たせられたりしたらいいけど。
0216デフォルトの名無しさん
垢版 |
2020/09/25(金) 07:58:20.78ID:ZK6gJNpW
>>214
クロージャならやってくれるから技術としては可能だけど、
関数として定義するなら関数仕様としてimpl Traitまでは書こうねということと解釈している
0217デフォルトの名無しさん
垢版 |
2020/09/25(金) 19:12:30.94ID:yo3ZA1rx
>>215
いまさらどうにもならないが、使いはじめの頃は、もっと視認性のあるフレーズ使ってくれてたらなぁと思ってた。

例えば、F#の
hofe |> ignore
なんかは、冗長ではあるが逆に視認性も良く、捨てる気満々の書き方で気に入ってる。
0220デフォルトの名無しさん
垢版 |
2020/09/26(土) 06:07:19.66ID:Jy/kksq4
コンピューターはともかく、人間にはreturnくらいの文字的冗長性があった方が視認性がいい。
0222デフォルトの名無しさん
垢版 |
2020/09/26(土) 09:30:48.93ID:en54jqZM
>>220
returnがあればearly returnだと識別できるのでその意味では視認性は高い
ただセミコロンというC系言語経験者が注視しない記号に新しく重要な意味をもたせたから戸惑う

>>221
ifブロック末尾のセミコロンは常に省略できるわけじゃない
https://doc.rust-lang.org/reference/statements.html#expression-statements


セミコロンがないと意図通りパースできないケースってほとんどないと思うので
そのうちJSのASIのようなものでセミコロン不要になる未来もある気がする
0223デフォルトの名無しさん
垢版 |
2020/09/26(土) 10:01:37.83ID:GOW7LNc9
個人的にはセミコロンうんぬんよりifの中括弧が苦痛

/* c */
#include <stdio.h>
#define min(a, b) ((a) < (b) ? (a) : (b)) // スッキリ
int min2(int a, int b) {return a < b ? a : b;} // ややスッキリ
int min3(int a, int b) {
if (a < b) return a; else return b; // スッキリ?
}
int main() {
printf("%d ", min(3, 2));
printf("%d ", min2(3, 2));
printf("%d ", min3(3, 2));
return 0;
}

// rust
fn main() {
let min = |a, b| if a < b {a} else {b}; // 中括弧が嫌
//let min = |a, b| if (a < b) a else b; // これならスッキリ
//let min = |a, b| if a < b then a else b; // あるいはこれ
println!("{}", min(3, 2));
}

(* ocaml *)
let min a b = if a < b then a else b (* スッキリ *)
let () = print_int (min 3 2)
0227デフォルトの名無しさん
垢版 |
2020/09/26(土) 14:34:05.78ID:d+bfMgei
>>225
本文 (?) の波括弧が必須だから
条件式の範囲は自明 (視認性的に) だってことなんだろうな。
0229デフォルトの名無しさん
垢版 |
2020/09/26(土) 16:28:05.98ID:en54jqZM
>>228
PythonというよりRubyだろね
コアチームは過去も含めてRubyコミュニティ出身者が多いから

モジュールはPythonのようにファイルベースじゃなくキーワードで名前空間をきちんと切るし
クロージャの書き方だったりreturnを書かない慣習だったりも他言語に比べて類似性が高い
0230デフォルトの名無しさん
垢版 |
2020/09/26(土) 16:42:46.56ID:d+bfMgei
型システムは ML 系の言語でよくあるやつだし、
そっち方面の影響もあるんじゃないの?
0234デフォルトの名無しさん
垢版 |
2020/09/27(日) 04:32:18.28ID:Wycq4Ck4
セミコロンとかはEdition上げて撤廃してほしいけど、ここまでRustのOSS書かれてたら無理だろなぁ...
0236デフォルトの名無しさん
垢版 |
2020/09/27(日) 08:00:03.20ID:6sIZ9RBB
Rust, Go, Elixir などの新しい言語は、Ruby の影響が強い。
Ruby で最も良いのは、すべての進数の数値リテラルに、_ を含められること

こういうコメントを書かなくて済む
1000000 // 1_000_000
0237デフォルトの名無しさん
垢版 |
2020/09/27(日) 09:53:51.56ID:xq8pY9v9
戻り値の有無がセミコロンだけで区別されている現状をどうにかしないとそもそもセミコロン廃止なんて
無理だろうけど、セミコロンレスってそんなにいいかねぇ?

行の折り返しを間違えて別の文になってしまってもスルーされる場合があるのがなんか嫌。
ASIがあるJSでもメジャーどころのスタイルガイドはみんなASIを信用しないでセミコロン使うことに
なっているし。
pythonだとセミコロン使わないスタイルも多いけど、あっちはインデントで判別できるしね。
0238デフォルトの名無しさん
垢版 |
2020/09/27(日) 10:45:39.75ID:5NvF/cEJ
>>237
>ASIを信用しないでセミコロン使うことに

ASIを信用してないわけじゃないよ
ASIの仕様はJSの仕様で決まってるから例外的に挿入されない場合もはっきり分かってる
セミコロンを使うスタイルが多いのはミニファイとかを考慮してるから

JSの場合は普通に書いてる分にはセミコロンの有無でほぼ違いが無い上に
セミコロンレスで書いてもリンター使って自動挿入できるから実質書き手の自由
1行に複数文書いてるときでもなければセミコロンに特別な意味はないから気にする必要がない
0239デフォルトの名無しさん
垢版 |
2020/09/27(日) 11:08:19.83ID:OQ0JAVEc
セミコロンは基本的にはあっていいけどたまに}のあとに;必要なやつとかあったりしてこれはイヤ
0240デフォルトの名無しさん
垢版 |
2020/09/27(日) 11:27:51.54ID:xq8pY9v9
たしかに「ASIを信用しないで」というと疑っているみたいだから「依存しないで」の方が
適切だったかも。
いずれにしても、どのスタイルガイドもプログラマの意図と異なる判断がされる危険を
挙げていて、それを防ぐためには明示的にセミコロンを記述する方が良いと謳っている。
minifyはそれこそminify時にセミコロンを補完すればいいんだから関係ないと思う。
0243デフォルトの名無しさん
垢版 |
2020/09/27(日) 12:27:31.82ID:MoLnvbgN
セミコロン書き忘れる事は多々あるけど、意図しない値が返ってとかならない(はず)なので別に困らない
それより、Docs.rsに見にくいクレートが有る方が困る、AutoとBlanket以外のShow hidden undocumented itemsを
デフォルトで展開するオプションが有れば良いのに、この議題はどっかで見たような気がする。
0244デフォルトの名無しさん
垢版 |
2020/09/27(日) 12:34:01.78ID:FTgnsV+4
>>241
1967のPL/Iあたりからかな?登場時期からするともっと広まってもおかしくなかった気もするけど、16/32ビットリテラルしかなかった時代には需要なかったんだろうね。verilogは何ビットでもいけるから必要だけど。
最近は128ビット型とかBigIntとかでようやく必要になってきたってことか。
0245デフォルトの名無しさん
垢版 |
2020/09/27(日) 12:55:24.47ID:ePGxxCtX
rustのAPI documentなんか読みづらい気がする
うまく説明できないけど

型クラスのあたりも見づらい
0246デフォルトの名無しさん
垢版 |
2020/09/27(日) 13:55:00.63ID:5NvF/cEJ
>>240
きちんとした手順にそったminifyだけを指して言ったわけじゃないんだが
GoogleやAirbnbのstyle guideを見ると確かにそういう意図ではないみたいだね
npmやGithubみたいにセミコロンレスのstandard style使ってるところも多いから
「メジャーどころはみんなセミコロンを明示的に書く」というのはちと言い過ぎかな

いずれにしろJSの場合は1コマンドで一瞬で切り替え可能で書く時はどっちでいいから
Rustとはかなり事情が違うと思う
0247デフォルトの名無しさん
垢版 |
2020/09/27(日) 14:15:05.14ID:5NvF/cEJ
>>242
探してみたらRFCあったけどCloseされてた
https://github.com/rust-lang/rfcs/issues/2583

C/C++/G#/Javaあたりから来た人はセミコロンあるのが普通だろうけど
Go/Scala/Swift/Kotlin/Ruby/Pythonだとセミコロンないのが普通なので面倒くさく感じるのよ

RFCのやり取りや↓ここの議論を見るとセミコロンが不要になる可能性はもうないね
https://internals.rust-lang.org/t/make-some-separators-optional/4846
0248デフォルトの名無しさん
垢版 |
2020/09/27(日) 15:12:03.29ID:FTgnsV+4
セミコロンレスってフォーマット的な改行と文末の改行を文脈を見て判断する必要があるから好きじゃないなぁ。
一文が複数行になりやすいビルダーパターンとかイテレータアダプタの類いが特に。
入力する側としてはほとんど無意識に打ってるから特に面倒とも感じないし。
0251デフォルトの名無しさん
垢版 |
2020/09/28(月) 01:45:21.81ID:1Vhx5XJ3
>>223
ocamlってセミコロン必要じゃなかったっけ?
0253デフォルトの名無しさん
垢版 |
2020/09/28(月) 09:58:13.64ID:UVos1NUC
docsのフロント部分は特に強いUXデザイナーがいない感じがすごくする
0254デフォルトの名無しさん
垢版 |
2020/09/28(月) 18:49:05.66ID:5HiAAmxH
>>251
トップレベルの分を区切るのに;;を使う
ただしletの直前、ファイルの最後、などでは省略できる
https://ocaml.org/learn/tutorials/structure_of_ocaml_programs.ja.html
構文は
https://ocaml.org/releases/4.11/htmlman/language.html

let min a b = if a < b then a else b (* letの直前だから;;省略 *)
let () = print_int (min 3 2) (* ファイルの最後だから;;省略 *)
0255デフォルトの名無しさん
垢版 |
2020/10/01(木) 14:03:33.62ID:WCPslwmj
slice::windowsのstrバージョンみたいなのってないのでしょうか。
ようするにある文字列に含まれる連続するn文字を頭から順に返すイテレータを作ってくれるようなやつです。
0256デフォルトの名無しさん
垢版 |
2020/10/01(木) 18:29:40.74ID:HHhjPj0U
>>255
ないのでVec<char>を生成してwindowsを呼ぶとか

let cs: Vec<_> = String::from("あいうえお").chars().collect();
let ws: Vec<_> = cs.windows(2).map(|v| v.iter().collect::<String>()).collect();
0257デフォルトの名無しさん
垢版 |
2020/10/01(木) 18:54:04.45ID:i8Yvf3kp
文字幅が可変長 (utf-8) であっても windows みたいなことをするのはそんなにコスト大きくないよね?
ふたつのポインタを一文字ずつ進めるだけなんだから O(N) で出来るはず。
0258デフォルトの名無しさん
垢版 |
2020/10/02(金) 09:46:31.03ID:D4+ZSkLl
アロケートなしだと、
(0..s.len()-n).map(|i| &s[i..i+n])
となるけど自分で-nとか+nとかiとかやるのめっちゃアホくさいしそのうちミスりそう
0259デフォルトの名無しさん
垢版 |
2020/10/02(金) 14:20:31.00ID:iKrdrFom
>>258
アロケートなしならこれでもいけるはず。utf8を食わせると死ぬけど
.as_bytes().windows(2).map(|v| std::str::from_utf8(v).unwrap())
0260デフォルトの名無しさん
垢版 |
2020/10/08(木) 09:18:16.25ID:PyhRFgfx
アロケートなしっていっても結局collect::<Vec<_>>()するんだからなしって表現は違うくないか
0263デフォルトの名無しさん
垢版 |
2020/10/12(月) 16:21:28.62ID:Z3Kcjb2S
Vec<T>って既に有る要素の中身を修正する方法はありますか。
有れば教えていただければ幸いです。
0264デフォルトの名無しさん
垢版 |
2020/10/12(月) 16:28:10.38ID:Z3Kcjb2S
自分が見た本ではvec[0]でアクセスする例は出てなかったと思うのですが
今ネットで見たところ
let mut vec = Vec::new();
vec.push(1);
vec.push(2);
vec[0] = 7
という例がありました。
Vec<T>の要素Tが構造体の場合、
vec[0]のアドレスを参照で受け取ってアクセスするには
let &mut a=&v[0];
a.xxx = yyy;
でよいのでしょうか?
(基礎が分かって無いだけかもしれませんが)
0265デフォルトの名無しさん
垢版 |
2020/10/12(月) 16:30:35.47ID:ldeP4Qys
.get
.get_mut
0266デフォルトの名無しさん
垢版 |
2020/10/12(月) 16:48:39.55ID:Z3Kcjb2S
>>265
有難うございます。getは載っていたのですが get_mut は知りませんでした。
さらに質問させてください。
Vecに対する[]演算子のメソッド名(?)は何でしょうか?
0270デフォルトの名無しさん
垢版 |
2020/10/12(月) 19:50:22.11ID:ldeP4Qys
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2018&gist=a388e403b6cd7afe902a9fd8618b5a65

質問内容とブレてたらごめんなさい
0271デフォルトの名無しさん
垢版 |
2020/10/12(月) 19:53:01.17ID:P0Nqqpd2
TがCopyだと let &mut a = &mut v[0]; ならコンパイル通っちゃうのは落とし穴かもしれない
0275デフォルトの名無しさん
垢版 |
2020/10/20(火) 19:00:44.91ID:CHq3Beyq
勉強始めたばかりですが変数のシャドーイングって必要ですか?

なんとなくグローバルに置いた変数もシャドーイングできそうなのですが実害は出たことありますか?
多分ないと思いますが…
0277デフォルトの名無しさん
垢版 |
2020/10/20(火) 20:46:27.74ID:7hmMXh1W
デバッグやバグ修正に必要なエネルギーコストを加味したらCより効率よくなりそう
0279デフォルトの名無しさん
垢版 |
2020/11/01(日) 07:27:17.14ID:an3UASXf
let mut bt = (0..10).collect::<BTreeSet<_>>();
for e in bt.iter() {

// ここで条件に一致する要素をbtから削除したい

}
こんな感じのものを作りたくなったのですがどうすればいいのでしょうか?

うまい具合にやる方法が思いつかなくて以下のようにやっているのですが、なんというかすごくアホくさいというか・・・

let mut bt = (0..10).collect::<BTreeSet<_>>();
let mut temp = Vec::new()
for e in bt.iter() {
if e == Foo { temp.push(e); } // 削除予定のものをtempに入れる
}
for e in temp {
bt.remove(&e);
}
0281デフォルトの名無しさん
垢版 |
2020/11/01(日) 13:38:40.42ID:an3UASXf
btがこの例のとおりのものならそれでいいんですけど、
いろんな状況でbtに要素が追加されるっていう感じです

あと、if e == Fooはちょっと雑すぎましたif is_xxx(e)とかのほうがよいです
0282デフォルトの名無しさん
垢版 |
2020/11/01(日) 17:37:39.36ID:o3MRCmTo
コンテナのイテレーターのループ回してる間にコンテナの要素を追加や削除は出来ない。これは他のコンテナ(Vecなど)でもそう。どうしてもやるなら内部実装を理解した上でunsafeな方法で。
「いろんな状況でbtに要素が追加される」がループ中なのか何なのか分からないのでどうしようもないが、
let bt = bt.into_iter().filter(|&e| e == foo).collect::<std::collections::BTreeSet<_>>();
で新たなbtを作るか、
もとのbtから要素を削除するにしても
for e in bt.iter().filter(|&&e| e == foo).cloned().collect::<Vec<_>>() {
bt.remove(&e);
}
などでもう少し簡潔に書ける。
0283デフォルトの名無しさん
垢版 |
2020/11/01(日) 18:31:04.97ID:adfXjKjb
BTreeSet::drain_filter が安定化されるのを待とう

std::collections の unatable な機能を含めて切り出した crate とかあれば良いのに
0286デフォルトの名無しさん
垢版 |
2020/11/06(金) 03:44:45.46ID:S3a0GE/K
Rust book 構造体の章の以下のコード片なんですが
let mut user1 = User {
email: String::from("someone@example.com"),
email: String::from("someusername123"),
active: true,
sign_in_count: 1,
}

user1.email = String::from("another@example.com");
//コード片ここまで

最後の行でどこからも参照されなくなった元の
String::from("someone@example.com")
は、どういう理屈で解放されるんでしょうか?
もしGC言語なら最後の行でGC対象になるとこですけど。
Rust bookのこれ以前の章で、変数がスコープを外れるときdropが呼ばれることの説明はあったのですが、変数の束縛外れちゃったStringはいつ、どこで?
0287デフォルトの名無しさん
垢版 |
2020/11/06(金) 04:09:10.53ID:2cok4roU
>>286
最後の行でdropされるのは同じ
初期化済みの変数に新しい値を束縛したら古い値はdropされる
0288デフォルトの名無しさん
垢版 |
2020/11/06(金) 04:35:01.60ID:B4UB4dMh
>>287
ありがとうございます。
変数にバインドされてるヒープ領域がdropされるのはその変数がスコープを抜ける}の時ですよね。
>>286
初期化済みの変数に新しい値を束縛してる
user1.email = String::from("another@example.com");
から、
スコープが閉じる}まで、元の
String::from("someone@example.com")
のヒープ領域は解放されないということでしょうか?
user1.email = String::from("another@example.com");
の直後に解放されるのではなく?
0290デフォルトの名無しさん
垢版 |
2020/11/06(金) 08:36:34.29ID:HarnCsHz
考えてみりゃ確かにunstableのcrateってめっちゃいい案だな
use unstable::prelude::*;
で全部取り込める上にバージョンあげたらunstableから無くなってstdの方が挿し代わって使われるし
0291デフォルトの名無しさん
垢版 |
2020/11/06(金) 08:47:23.44ID:mKCogF8p
明らかに可読性悪い言語なのだがあと5年くらいしたらこの界隈も気づくかもね
0292デフォルトの名無しさん
垢版 |
2020/11/06(金) 08:54:20.60ID:wXTP989a
5年先いくパイセン降臨
0296デフォルトの名無しさん
垢版 |
2020/11/06(金) 20:08:48.42ID:g6FZ2Lxp
>>291
esolangはさておきAPLとかは難読言語といっても良いかも
あとは暗黙の○○が多い言語や記号が多い言語は初心者にとっては難読だと思うけど
Rustはこれらには当てはまらないと思うけど、どういう点で難読と思ったのか教えて欲しい
0297デフォルトの名無しさん
垢版 |
2020/11/11(水) 20:37:16.07ID:ZuM/CkEs
>>291
お前は5年後もC++使ってろよ
0298デフォルトの名無しさん
垢版 |
2020/11/12(木) 10:54:00.16ID:uK53dAw4
fn foo(bar: impl Buzz)
というシグネチャは、
fn foo<T: Buzz>(bar: T)
の構文糖なんですよね?

では、
fn foo() -> impl Buzz
を、
fn foo<T: Buzz>() -> T
と書けないのはなぜなんでしょう?
0302デフォルトの名無しさん
垢版 |
2020/11/12(木) 16:23:24.97ID:tcFc7SO9
>>301
マジか
どっちも書いてる人は同じだから
引数ポジションについては細かい違いはあってもシンタックスシュガーなのかも

ただ戻り値ポジションの場合は
ジェネリックでは書き直せないから確実に違う
0303デフォルトの名無しさん
垢版 |
2020/11/12(木) 18:49:52.91ID:C+/hhwIt
記号が多い言語は英語の苦手な日本人には有利だ
英文に近づけようとする言語は不利だ
0311デフォルトの名無しさん
垢版 |
2020/11/14(土) 13:14:02.66ID:DnZAmAgg
The name "turbofish" was made up by reddit user deadstone in 2015, and has since caught on in the Rust community, being used even in the official documentation.
「turbofish」という名前は、2015年にredditユーザーのdeadstone氏によって作成され、それ以来Rustコミュニティで定着し、公式ドキュメントでも使用されています。
■ このスレッドは過去ログ倉庫に格納されています

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