Mozilla発のRust言語のスレ
公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust
Web上の実行環境
https://play.rust-lang.org
前スレ
Rust Part7
http://mevius.5ch.net/test/read.cgi/tech/1563114707/
Rust part8
■ このスレッドは過去ログ倉庫に格納されています
2020/01/24(金) 11:47:52.41ID:9oO1hUHl
322デフォルトの名無しさん
2020/03/30(月) 04:01:22.73ID:/1SwYHDd >>318が書いてるの合ってると思うけど?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6d886f2d3b944871c18856f0e19da71c
iterがshared referenceをイテレートするから
パターンマッチで`&`を1枚剥がした型にして使ってる
for &i in iterと同じ
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6d886f2d3b944871c18856f0e19da71c
iterがshared referenceをイテレートするから
パターンマッチで`&`を1枚剥がした型にして使ってる
for &i in iterと同じ
323デフォルトの名無しさん
2020/03/30(月) 04:40:37.32ID:Oymj8mf6324デフォルトの名無しさん
2020/03/30(月) 04:45:30.74ID:Oymj8mf6 誤: let x:&i32 = y;
正: let x:&i32 = &y;
正: let x:&i32 = &y;
325デフォルトの名無しさん
2020/03/30(月) 11:38:27.40ID:/1SwYHDd >>323
左辺に代入する時にパターンマッチ使ってDestructuringしてる
例えばyが&i32ならxはi32になる
let i = 1;
let &i = i;
これがコンパイル取らないのは
右辺がintegerで左辺がreferenceを要求しててマッチしないから
let i:i32 = 1;
let i = &i;
let &i = i;
let i:() = i;
↑こうやって試せば3行目の&iへの代入でiが&i32じゃなくi32になってるのが分かる
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1d23370e99b388e2205c43e863885315
左辺に代入する時にパターンマッチ使ってDestructuringしてる
例えばyが&i32ならxはi32になる
let i = 1;
let &i = i;
これがコンパイル取らないのは
右辺がintegerで左辺がreferenceを要求しててマッチしないから
let i:i32 = 1;
let i = &i;
let &i = i;
let i:() = i;
↑こうやって試せば3行目の&iへの代入でiが&i32じゃなくi32になってるのが分かる
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1d23370e99b388e2205c43e863885315
326デフォルトの名無しさん
2020/03/30(月) 14:27:14.40ID:Oymj8mf6327デフォルトの名無しさん
2020/03/30(月) 14:34:27.40ID:yinACqvq328デフォルトの名無しさん
2020/03/30(月) 15:23:14.22ID:/1SwYHDd 1.38からはstd::any::type_nameがstabilizeされてるので
エラーメッセージやnightly使わずに変数の型をprintして確認できるみたい
(consumeしないようにreferenceで渡すから少し分かりにくいかもだけど)
fn type_of<T>(_: &T) -> &str {
std::any::type_name::<T>()
}
fn main() {
let i = 1;
let i = &i;
let &i = i;
println!("{}", type_of(&i));
}
type_name_of_valってのも追加されてるけど
こっちはまだstabilizeされてない
エラーメッセージやnightly使わずに変数の型をprintして確認できるみたい
(consumeしないようにreferenceで渡すから少し分かりにくいかもだけど)
fn type_of<T>(_: &T) -> &str {
std::any::type_name::<T>()
}
fn main() {
let i = 1;
let i = &i;
let &i = i;
println!("{}", type_of(&i));
}
type_name_of_valってのも追加されてるけど
こっちはまだstabilizeされてない
329デフォルトの名無しさん
2020/03/30(月) 16:45:46.87ID:Oymj8mf6330デフォルトの名無しさん
2020/03/30(月) 18:21:13.55ID:/1SwYHDd >>329
聞く前に試せばわかるよね
聞く前に試せばわかるよね
331デフォルトの名無しさん
2020/03/30(月) 18:43:59.32ID:QPHAwv8T /1SwYHDd氏やるなぁ
こういう細かいことまで知ってる人のRust歴気になる
こういう細かいことまで知ってる人のRust歴気になる
332デフォルトの名無しさん
2020/03/31(火) 00:49:28.04ID:bdtzxXSI さっきオナラしようとしたらウンチが少し出てしまったんだけど
ばれてないからいいよね ごめんね
ばれてないからいいよね ごめんね
333デフォルトの名無しさん
2020/03/31(火) 03:36:52.65ID:Hb9bQaKd 在宅だったら放屁は自由
334デフォルトの名無しさん
2020/03/31(火) 13:51:38.31ID:Ow5tuxOJ う〜ん。 ちがうなぁ。
335デフォルトの名無しさん
2020/04/01(水) 05:04:17.87ID:2vQ3PjhV やりたいこと
Optionからの安全な値の取り出しを構文レベルで保証、およびNone時に数行の処理と戻り値を伴う正常の早期returnをしたい
if Some(v) = foo.get() {
安全に取り出せるがネストが嫌すぎる
} else {
位置が遠すぎる
}
let v = if Some(v) = foo.get() {
v 安全取り出しだが冗長すぎて嫌
} else {
}
let v = match foo.get() {
Some(v) => v 安全取り出しだが冗長すぎて嫌
None => { }
}
if foo.is_none() {
構文で保証されずプログラマの注意力次第で嫌すぎる
}
let v = foo.get().unwrap();
let v = foo.get().ok_or_else(||{
は?正常終了つってんだろが?エラー値で返すんじゃねえよバカか?
})?;
Optionからの安全な値の取り出しを構文レベルで保証、およびNone時に数行の処理と戻り値を伴う正常の早期returnをしたい
if Some(v) = foo.get() {
安全に取り出せるがネストが嫌すぎる
} else {
位置が遠すぎる
}
let v = if Some(v) = foo.get() {
v 安全取り出しだが冗長すぎて嫌
} else {
}
let v = match foo.get() {
Some(v) => v 安全取り出しだが冗長すぎて嫌
None => { }
}
if foo.is_none() {
構文で保証されずプログラマの注意力次第で嫌すぎる
}
let v = foo.get().unwrap();
let v = foo.get().ok_or_else(||{
は?正常終了つってんだろが?エラー値で返すんじゃねえよバカか?
})?;
336デフォルトの名無しさん
2020/04/01(水) 08:10:52.28ID:3tt/1DhK let v = foo?;
337デフォルトの名無しさん
2020/04/01(水) 08:19:02.46ID:2vQ3PjhV は?
338デフォルトの名無しさん
2020/04/01(水) 09:19:54.63ID:yrAQuZWY 構文を調整したいならマクロじゃない?
let v = safe_get!(v, {
失敗した
return Ok (());
});
みたいな。ベタ書き以外でearly returnしたいならマクロか?演算子みたいにコンパイラサポートがいると思う。
let v = safe_get!(v, {
失敗した
return Ok (());
});
みたいな。ベタ書き以外でearly returnしたいならマクロか?演算子みたいにコンパイラサポートがいると思う。
339デフォルトの名無しさん
2020/04/01(水) 10:13:55.16ID:0Fs3VJge なんでboolって1byteあるの?
340デフォルトの名無しさん
2020/04/01(水) 11:20:10.79ID:5VJq6KKK C は bit field あるのにな
341デフォルトの名無しさん
2020/04/01(水) 11:25:37.12ID:qjrNWUcZ >>335
map_or_elseでSomeの時とNoneの時に適用するクロージャを渡せる
でもどうしても1行で書きたいとかchainしたい場合じゃなければ普通にmatchかif-else使うな
fn foo(){
get().map_or_else(|| bar(), |x| baz(x))
}
fn foo(){
match get() {
None => bar(),
Some(x) => baz(x)
}
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=dd9040426e54f1dfc6e39d07bbd219fb
map_or_elseでSomeの時とNoneの時に適用するクロージャを渡せる
でもどうしても1行で書きたいとかchainしたい場合じゃなければ普通にmatchかif-else使うな
fn foo(){
get().map_or_else(|| bar(), |x| baz(x))
}
fn foo(){
match get() {
None => bar(),
Some(x) => baz(x)
}
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=dd9040426e54f1dfc6e39d07bbd219fb
342デフォルトの名無しさん
2020/04/01(水) 11:30:33.60ID:eoE2gHM2 >>341
クロージャ渡しじゃearly returnできないって話では?
クロージャ渡しじゃearly returnできないって話では?
343デフォルトの名無しさん
2020/04/01(水) 12:21:13.46ID:qjrNWUcZ344デフォルトの名無しさん
2020/04/01(水) 13:43:58.79ID:npfcBiID345デフォルトの名無しさん
2020/04/01(水) 14:12:02.37ID:Wuhu+msT ネストが嫌なんだから無理でしょ
ネストしないコードを書く人なんだろうけど
ネストしないコードを書く人なんだろうけど
346デフォルトの名無しさん
2020/04/01(水) 17:06:40.66ID:qjrNWUcZ >>344
なるほど理解した
どうしてもearly returnがしたくてunwrapも嫌なら
if letを2回やるか、is_none+if let Someでもいい気がする
マクロ書いてもidiomaticな形に比べて読みやすくなるかっていうと微妙なので
fn foo(x: &str) -> Result<()>{
let v = safe_get!(get(x), { …; return Ok(()) });
let v = baz(v)?;
qux(v)?
}
fn foo(x: &str) -> Result<()>{
if let Some(v) = get(x) {
let v = baz(v)?;
qux(v)?;
}
Ok(())
}
なるほど理解した
どうしてもearly returnがしたくてunwrapも嫌なら
if letを2回やるか、is_none+if let Someでもいい気がする
マクロ書いてもidiomaticな形に比べて読みやすくなるかっていうと微妙なので
fn foo(x: &str) -> Result<()>{
let v = safe_get!(get(x), { …; return Ok(()) });
let v = baz(v)?;
qux(v)?
}
fn foo(x: &str) -> Result<()>{
if let Some(v) = get(x) {
let v = baz(v)?;
qux(v)?;
}
Ok(())
}
347デフォルトの名無しさん
2020/04/01(水) 19:39:22.27ID:2vQ3PjhV "処理と戻り値"を伴う""正常""の早期returnをしたいといってるだろがErrでラップして返すとかバカか?
こういうSomeから取り出すだけの部分が冗長だから消えてなくなれつってんだよ
is_none()でやるのは構文保証ではなく"プログラマーの注意力"による保証だからクソだつってんだよ
let v = match foo.get() { Some(v) => v, None => {
bar.modify();
baz.modify();
return Ok(bar, baz);
}};
let v = if let Some(v) = foo.get() { v } else {
bar.modify();
baz.modify();
return Ok(bar, baz);
}};
こういうSomeから取り出すだけの部分が冗長だから消えてなくなれつってんだよ
is_none()でやるのは構文保証ではなく"プログラマーの注意力"による保証だからクソだつってんだよ
let v = match foo.get() { Some(v) => v, None => {
bar.modify();
baz.modify();
return Ok(bar, baz);
}};
let v = if let Some(v) = foo.get() { v } else {
bar.modify();
baz.modify();
return Ok(bar, baz);
}};
348デフォルトの名無しさん
2020/04/01(水) 20:41:14.76ID:SX13wyIA349デフォルトの名無しさん
2020/04/01(水) 20:49:40.54ID:/Onfa91A 宣言的な書き方の基本が分かってないんやろな
Rust以前のレベル
Rust以前のレベル
350デフォルトの名無しさん
2020/04/01(水) 21:05:02.98ID:SX13wyIA351デフォルトの名無しさん
2020/04/01(水) 21:36:42.23ID:SEIF3iTR 言語としても長い間議論があったみたいだけど、まとまらなかったみたいね
https://github.com/rust-lang/rfcs/pull/1303
https://github.com/rust-lang/rfcs/pull/1303
352デフォルトの名無しさん
2020/04/01(水) 21:36:47.02ID:qjrNWUcZ >>347
>"処理と戻り値"を伴う""正常""の早期returnをしたいといってるだろがErrでラップして返すとかバカか?
えっ、 Errでラップして返してる?
まぁそれはいいとしてearly returnだけじゃなく
戻り値の型と取り出した値をどうするかをセットで考えてないから
そうなっちゃうんだと思うよ
>"処理と戻り値"を伴う""正常""の早期returnをしたいといってるだろがErrでラップして返すとかバカか?
えっ、 Errでラップして返してる?
まぁそれはいいとしてearly returnだけじゃなく
戻り値の型と取り出した値をどうするかをセットで考えてないから
そうなっちゃうんだと思うよ
353デフォルトの名無しさん
2020/04/01(水) 22:01:23.20ID:SX13wyIA RFCざっと見てきたけど、あっちでも
「map_errでいいんじゃ?」「return;できねーよ」ってやってるな。
そんなに難解なリクエストでもないと思うんだが。
「map_errでいいんじゃ?」「return;できねーよ」ってやってるな。
そんなに難解なリクエストでもないと思うんだが。
354デフォルトの名無しさん
2020/04/01(水) 22:20:38.50ID:0Fs3VJge fn check<T>(mut f: impl FnMut(T) -> bool)
と
fn check<T, F>(mut f: F)
where F: FnMut(T) -> bool
って同意義ですか?
と
fn check<T, F>(mut f: F)
where F: FnMut(T) -> bool
って同意義ですか?
355デフォルトの名無しさん
2020/04/02(木) 03:46:30.54ID:0zdT1xZ7356デフォルトの名無しさん
2020/04/02(木) 03:48:18.19ID:0zdT1xZ7 なお、このような場合の whereは、日本人感覚からすれば、ifと読み替えてもいい。
357デフォルトの名無しさん
2020/04/02(木) 05:35:03.07ID:zwgg3bUK 前者の場合 check::<T, F>() でコールできるが後者はできない
358デフォルトの名無しさん
2020/04/02(木) 17:07:56.47ID:SaXsz2/b 前者と後者が逆?
359デフォルトの名無しさん
2020/04/02(木) 20:28:06.36ID:7RFFBbbD これ
https://docs.rs/try_or/0.2.0/try_or/macro.try_opt_or_else.html
Unwraps an Option. If the result is None, calls the function $or_fn and returns its result.
https://docs.rs/try_or/0.2.0/try_or/macro.try_opt_or_else.html
Unwraps an Option. If the result is None, calls the function $or_fn and returns its result.
360デフォルトの名無しさん
2020/04/02(木) 21:53:44.49ID:zwgg3bUK >>358
逆にだったすまん
逆にだったすまん
361デフォルトの名無しさん
2020/04/02(木) 23:30:20.89ID:SaXsz2/b そもそもcheck::<T, F>()じゃ引数渡してないから呼び出せなくない? 試してないけど
362デフォルトの名無しさん
2020/04/03(金) 00:13:24.70ID:RIPEgpHK 構文で解決すべきところを皆が俺俺マクロで解決して統一感ない状態を生むのが良いと考えるやついるのか?
363デフォルトの名無しさん
2020/04/03(金) 00:44:31.97ID:11HfTHW1 if foo.is_none() {
シンプルにこれでいいと思うんだが...
これぐらいの細かい挙動で構文拡張しろとかマクロ書けとかなったらC++みたいになっていくのが目に見えるしから嫌だわ
しかもこんな嫌だ嫌だ言ってて質問する立場なのにこんな逆ギレもしてて救いようがない
シンプルにこれでいいと思うんだが...
これぐらいの細かい挙動で構文拡張しろとかマクロ書けとかなったらC++みたいになっていくのが目に見えるしから嫌だわ
しかもこんな嫌だ嫌だ言ってて質問する立場なのにこんな逆ギレもしてて救いようがない
364デフォルトの名無しさん
2020/04/03(金) 00:44:38.25ID:8O7qKRUc 現状は335が冗長と言う状態で統一されてるんだからいいんじゃないの。
その冗長さをどうしても許容できない人は(少数派である以上)マクロで解決するしかないし、もし大多数が賛同できる新構文を思い付いたならRFC出せばいい。
その冗長さをどうしても許容できない人は(少数派である以上)マクロで解決するしかないし、もし大多数が賛同できる新構文を思い付いたならRFC出せばいい。
365デフォルトの名無しさん
2020/04/03(金) 14:52:15.88ID:11HfTHW1 test bench_test ... bench: 111,111 ns/iter (+/- 11,111)
ベンチマークの +/- ってどういう意味?
ベンチマークの +/- ってどういう意味?
366デフォルトの名無しさん
2020/04/03(金) 15:47:04.36ID:uTu5qR57 >>363
is_none()は==NULLや==nilと同じ書き忘れのリスクを伴う"プログラマの注意力"を消耗するだけのゴミだろ
is_none()は==NULLや==nilと同じ書き忘れのリスクを伴う"プログラマの注意力"を消耗するだけのゴミだろ
367デフォルトの名無しさん
2020/04/03(金) 17:29:34.32ID:q/cvlU88 >>365
サンプルのmax - min
https://github.com/rust-lang/rust/blob/master/src/libtest/bench.rs#L57
min, maxは上下5%の外れ値処理をした後のものみたい
サンプルのmax - min
https://github.com/rust-lang/rust/blob/master/src/libtest/bench.rs#L57
min, maxは上下5%の外れ値処理をした後のものみたい
368デフォルトの名無しさん
2020/04/03(金) 19:54:55.15ID:CGYa3yhA if letやmatchにしないとSomeだったときの処理書けないしょ
369デフォルトの名無しさん
2020/04/03(金) 23:35:51.11ID:gSdeIOHU 最近勉強し始めたんだけどムズすぎ😭
370デフォルトの名無しさん
2020/04/04(土) 00:07:28.35ID:cnL2FB3T rust実用化に成功したプロジェクトって何があるの?お前らの会社では成功してるの?
371デフォルトの名無しさん
2020/04/04(土) 00:29:58.91ID:hnhE9+15 実用化って何
372デフォルトの名無しさん
2020/04/04(土) 01:42:27.61ID:R4+HYdkE rustで作ったメカの中でセックスしましたみたいな
373デフォルトの名無しさん
2020/04/04(土) 04:16:29.04ID:aJleCvsu use chrono::{Utc, TimeZone};
assert_eq!(Utc.ymd(2015, 5, 15).to_string(), "2015-05-15UTC");
なんでこれって静的メソッドじゃないのにself省略で使えるんですか?
https://docs.rs/chrono/0.4.11/chrono/offset/trait.TimeZone.html#method.ymd
assert_eq!(Utc.ymd(2015, 5, 15).to_string(), "2015-05-15UTC");
なんでこれって静的メソッドじゃないのにself省略で使えるんですか?
https://docs.rs/chrono/0.4.11/chrono/offset/trait.TimeZone.html#method.ymd
374デフォルトの名無しさん
2020/04/04(土) 08:43:05.69ID:ziV4A0+Z Utcはフィールドを持たないstructだから
イメージ的にはUtc{}.ymdとしているかんじ
イメージ的にはUtc{}.ymdとしているかんじ
375デフォルトの名無しさん
2020/04/04(土) 11:37:00.81ID:oHbtMe0Y Unit-like structsってやつだね
376デフォルトの名無しさん
2020/04/04(土) 16:49:30.52ID:aJleCvsu 公開されていないLoopStateっていうenum使いたいんですけどコンパイラーオプションとか属性とかで使う方法ありませんか?
https://doc.rust-lang.org/src/core/iter/mod.rs.html#371-422
https://doc.rust-lang.org/src/core/iter/mod.rs.html#371-422
377デフォルトの名無しさん
2020/04/04(土) 17:26:12.04ID:9lNQDQEm pub が付いてないものをそんなに簡単に使えたらモジュールの意味がないやろ……。
378デフォルトの名無しさん
2020/04/04(土) 17:26:43.72ID:9lNQDQEm そのモジュールをコピペして新しいモジュールを作れば自由に出来るんとちゃう?
379デフォルトの名無しさん
2020/04/04(土) 20:00:52.19ID:BQ+xJjAs Docs.rsのメソッドの引数の見方がわからん
具体的には
https://docs.rs/image/0.23.2/image/struct.Frames.htmlの
pub fn new(iterator: Box<dyn Iterator<Item = ImageResult<Frame>> + 'a>) -> Self
具体的には
https://docs.rs/image/0.23.2/image/struct.Frames.htmlの
pub fn new(iterator: Box<dyn Iterator<Item = ImageResult<Frame>> + 'a>) -> Self
380デフォルトの名無しさん
2020/04/04(土) 20:42:49.37ID:oHbtMe0Y iteratorを受け取ってSelfを返す。
iteratorは各要素がImageResult<Frame>のもの
Box<dyn …>してるのはコンパイル時にTrait ObjecのSizeが決まるようにするため
(Generics使えば不要)
‘aはiteratorのlifetimeをSelfのlifetimeにするため
iteratorは各要素がImageResult<Frame>のもの
Box<dyn …>してるのはコンパイル時にTrait ObjecのSizeが決まるようにするため
(Generics使えば不要)
‘aはiteratorのlifetimeをSelfのlifetimeにするため
381デフォルトの名無しさん
2020/04/04(土) 22:54:06.10ID:BQ+xJjAs382デフォルトの名無しさん
2020/04/05(日) 10:19:35.11ID:LNp8foc9 >>381
dyn は C++ で言う抽象クラスみたいなもんだよ。
トレイトオブジェクトというのは実際にはそのトレイトを実装している様々な型の可能性があって、
それら全てを格納可能な大きさはわからない。
Box は C/C++ でいうポインタみたいな用途で使われる。
大きさがわからなくてもオブジェクトの場所を指すことは出来る。
「そのトレイトを実装している型ならなんでも」と「そのトレイトを実装している型のいずれか」というのは違う意味で、
ジェネリクスは後者。
言い換えると、実行時にディスパッチされる多相とコンパイル時にディスパッチされる多相ってこと。
コンパイル時に型がわかるのなら大きさもコンパイル時にわかる。
大きさがわかるなら Box を経由しなくていい。
ライフタイムの 'a は Frames の型引数の 'a と同じだから、
new の返り値 (Self) の寿命は iterator の寿命と同じになる。
dyn は C++ で言う抽象クラスみたいなもんだよ。
トレイトオブジェクトというのは実際にはそのトレイトを実装している様々な型の可能性があって、
それら全てを格納可能な大きさはわからない。
Box は C/C++ でいうポインタみたいな用途で使われる。
大きさがわからなくてもオブジェクトの場所を指すことは出来る。
「そのトレイトを実装している型ならなんでも」と「そのトレイトを実装している型のいずれか」というのは違う意味で、
ジェネリクスは後者。
言い換えると、実行時にディスパッチされる多相とコンパイル時にディスパッチされる多相ってこと。
コンパイル時に型がわかるのなら大きさもコンパイル時にわかる。
大きさがわかるなら Box を経由しなくていい。
ライフタイムの 'a は Frames の型引数の 'a と同じだから、
new の返り値 (Self) の寿命は iterator の寿命と同じになる。
383デフォルトの名無しさん
2020/04/05(日) 11:42:45.53ID:/6aVgV0B Boxと&dynの違いって参照元がヒープかスタックかの違い?
384デフォルトの名無しさん
2020/04/05(日) 14:13:55.26ID:8bGOOvBY >>383
そう
そう
385デフォルトの名無しさん
2020/04/05(日) 14:35:00.95ID:8bGOOvBY >>381
大前提として変数や関数の引数や戻り値はコンパイル時にサイズが決まってないといけない
Iterator Traitを実装してる型を引数として受け取りたいからといって
`pub fn new(iterator: Iterator<…>) -> Self` と書くと
Iterator Traitのサイズがコンパイル時にはわからないのでコンパイルエラーになる
`let foo: str;`でエラーになるのと同じ
Box<dyn Trait>か&dyn Traitの形にすれば
Iterator Traitへの参照(=Trait Objectというfatポインタ)になって
受け渡しするサイズが固定されるのでエラーにならない
ジェネリクスを使って
`pub fn new<T: Iterator<…>>(iterator: T) -> Self` と書いた場合は
実際の呼び出しに使われているTの型ごとにコンパイラがバイナリを生成するので
コンパイル時にTのサイズが決まってる (impl Trait使った場合も同じ)
>>382も書いてるように前者は動的ディスパッチ、後者は静的ディスパッチなので
異なる型が混在するコレクションを使いたい時やバイナリサイズを小さくしたい時以外は
ジェネリクスを選ぶほうが一般的
大前提として変数や関数の引数や戻り値はコンパイル時にサイズが決まってないといけない
Iterator Traitを実装してる型を引数として受け取りたいからといって
`pub fn new(iterator: Iterator<…>) -> Self` と書くと
Iterator Traitのサイズがコンパイル時にはわからないのでコンパイルエラーになる
`let foo: str;`でエラーになるのと同じ
Box<dyn Trait>か&dyn Traitの形にすれば
Iterator Traitへの参照(=Trait Objectというfatポインタ)になって
受け渡しするサイズが固定されるのでエラーにならない
ジェネリクスを使って
`pub fn new<T: Iterator<…>>(iterator: T) -> Self` と書いた場合は
実際の呼び出しに使われているTの型ごとにコンパイラがバイナリを生成するので
コンパイル時にTのサイズが決まってる (impl Trait使った場合も同じ)
>>382も書いてるように前者は動的ディスパッチ、後者は静的ディスパッチなので
異なる型が混在するコレクションを使いたい時やバイナリサイズを小さくしたい時以外は
ジェネリクスを選ぶほうが一般的
386デフォルトの名無しさん
2020/04/05(日) 17:53:06.31ID:fOt2g8TG あーなんとなくわかってっきた
ジェネリクスと同じことがトレイトオブジェクトでも実現できて、その書き方がBox<dyn...>ということか
ジェネリクスと同じことがトレイトオブジェクトでも実現できて、その書き方がBox<dyn...>ということか
387デフォルトの名無しさん
2020/04/05(日) 19:06:03.32ID:LNp8foc9 同じことって言っちゃうと語弊がある気がするなぁ。
388デフォルトの名無しさん
2020/04/05(日) 21:52:05.83ID:/6aVgV0B そもそもRustはかなり型のサイズに厳しいけどなんで?
コンパイラの最適化のため?
コンパイラの最適化のため?
389デフォルトの名無しさん
2020/04/05(日) 22:38:29.83ID:8bGOOvBY >>388
他言語なら暗黙的に参照として扱われるようなものも
明示的に&を付けたりBox化することを求めるから厳しく感じるんだと思う
明示的に求めるのはowned/shared/mutableの3つを
一貫性を持って区別して書くようにっていう設計選択じゃないかな
>大前提として変数や関数の引数や戻り値はコンパイル時にサイズが決まってないといけない
↑これ他言語でも常識かもしれないけど自分はRustやるまで意識したことなかったよ
他言語なら暗黙的に参照として扱われるようなものも
明示的に&を付けたりBox化することを求めるから厳しく感じるんだと思う
明示的に求めるのはowned/shared/mutableの3つを
一貫性を持って区別して書くようにっていう設計選択じゃないかな
>大前提として変数や関数の引数や戻り値はコンパイル時にサイズが決まってないといけない
↑これ他言語でも常識かもしれないけど自分はRustやるまで意識したことなかったよ
390デフォルトの名無しさん
2020/04/05(日) 23:09:09.40ID:/qXmUwFk391デフォルトの名無しさん
2020/04/05(日) 23:12:44.10ID:/qXmUwFk 途中で送ってしもた。
rustでは当たり前に見えるけどこんな事してるのrustくらいでヒープが必要ならクロージャさえも自分でbox化する必要がある。
rustでは当たり前に見えるけどこんな事してるのrustくらいでヒープが必要ならクロージャさえも自分でbox化する必要がある。
392デフォルトの名無しさん
2020/04/05(日) 23:13:46.13ID:dvIeqTXE スタック上に長さ不定のデータが作れるとバグの温床になる。
他の言語だと大体の値がヒープに乗せること前提で動いているんで気にしたことが無いのだと思われる。
C/C++でも非推奨なんだけど、初心者向け釣りサイトでは平気でやってることがあるし、できちゃうから面倒
他の言語だと大体の値がヒープに乗せること前提で動いているんで気にしたことが無いのだと思われる。
C/C++でも非推奨なんだけど、初心者向け釣りサイトでは平気でやってることがあるし、できちゃうから面倒
393デフォルトの名無しさん
2020/04/06(月) 00:16:34.72ID:WU94L+3C 配列サイズが決められてないかつ、関数内で配列生成するけど返り値はサイズ固定のスライス記法の書き方するようにする方法ってない?
つまりはVecのアロケートが嫌な場合
fn name(v: Vec<A>) -> Vec<A> {
v.iter().map(***).collect
}
これだとスタック確保できるけど無駄なデータ入ってるし、動的なサイズの配列を返せない
fn name(v: Vec<A>) -> [i32; 10] {
let mut arr = [0; 10];
for (i, x) in v { arr[i] = x}
arr
}
こういうスライスのスタック版みたいな感じのことがしたい
fn name(v: Vec<A>) -> [A] {
let mut arr = [0; v.len()];
for (i, x) in v { arr[i] = x}
arr
}
つまりはVecのアロケートが嫌な場合
fn name(v: Vec<A>) -> Vec<A> {
v.iter().map(***).collect
}
これだとスタック確保できるけど無駄なデータ入ってるし、動的なサイズの配列を返せない
fn name(v: Vec<A>) -> [i32; 10] {
let mut arr = [0; 10];
for (i, x) in v { arr[i] = x}
arr
}
こういうスライスのスタック版みたいな感じのことがしたい
fn name(v: Vec<A>) -> [A] {
let mut arr = [0; v.len()];
for (i, x) in v { arr[i] = x}
arr
}
394デフォルトの名無しさん
2020/04/06(月) 00:54:32.32ID:jrbG9hxT395デフォルトの名無しさん
2020/04/06(月) 00:59:52.27ID:jrbG9hxT あと関数内部で配列生成したら
そのlifetimeが関数内に閉じるので参照も返せないね
そのlifetimeが関数内に閉じるので参照も返せないね
396デフォルトの名無しさん
2020/04/06(月) 01:07:26.57ID:jrbG9hxT やるとしたら
外側のスコープで固定サイズの配列をバッファとして作っておいて
関数ではバッファを満たして返すイメージ
外側のスコープで固定サイズの配列をバッファとして作っておいて
関数ではバッファを満たして返すイメージ
397デフォルトの名無しさん
2020/04/06(月) 01:16:22.32ID:FD55gb+K C言語でいうところの if ( (c=foo()) == bar) { ...(cを使う処理)
みたいなことやりたいんですがどうすればいいですか?
fooが結構重くて2回呼び出したくないのですが、
let c = foo();
if c == bar {...
とやるしかない?
みたいなことやりたいんですがどうすればいいですか?
fooが結構重くて2回呼び出したくないのですが、
let c = foo();
if c == bar {...
とやるしかない?
398デフォルトの名無しさん
2020/04/06(月) 01:49:32.44ID:JJIxYQHA matchとifガード使えば似たようなことは出来る
399デフォルトの名無しさん
2020/04/06(月) 02:48:45.03ID:WU94L+3C400デフォルトの名無しさん
2020/04/06(月) 03:03:32.80ID:jrbG9hxT >>397
@ bindingってのを使う
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b2a16356c2c790985ddd937ccc2ca826
@ bindingってのを使う
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b2a16356c2c790985ddd937ccc2ca826
401デフォルトの名無しさん
2020/04/06(月) 04:04:37.66ID:FD55gb+K >>398
match foo() {
c if c == bar => { .. },
_ => (),
}
こういう感じでしょうか。この場合だと記載量としてはかなり微妙ですが何かに使えそうなので覚えときます。
ありがとうございます。
>>399
今回の場合はfoo()がboolじゃないのと、barが変数なのでシャドーイングされてうまくいかないようです・・・。
if let foo @ bar = foo() { ...
みたいなことやろうとしましたがダメでした。
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d580f91c98f26cf52a23791489914ec3
match foo() {
c if c == bar => { .. },
_ => (),
}
こういう感じでしょうか。この場合だと記載量としてはかなり微妙ですが何かに使えそうなので覚えときます。
ありがとうございます。
>>399
今回の場合はfoo()がboolじゃないのと、barが変数なのでシャドーイングされてうまくいかないようです・・・。
if let foo @ bar = foo() { ...
みたいなことやろうとしましたがダメでした。
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d580f91c98f26cf52a23791489914ec3
402デフォルトの名無しさん
2020/04/06(月) 22:14:10.89ID:/YOLus+e403デフォルトの名無しさん
2020/04/06(月) 22:57:49.62ID:2RUK7fME Vecとかのコンテナ系の使い方は大分変わるよ
例えばイベント駆動の何かを作るときには考えた方が良いかと思う
struct XEventSource {
listeners : Vec<Box<dyn Handler>>,
...
}
trait Handler { fn handle(ev: &XEvent) -> () }
impl XEventSource {
fn addLisnter(&mut self, listener : Box<dyn Handler>) -> () {
self.listeners.push(listener);
}
fn emit(&self) -> () {
XEvent ev = ...;
for listener in listeners.iter() {
listener.handle(&ev);
}
}
}
みたいに作ると、利用者が好きに作った構造体でもHandlerをimplすればlistenersに足せる
ジェネリクスだとイベントリスナの実際の型1つしかaddできないので不便
例えばイベント駆動の何かを作るときには考えた方が良いかと思う
struct XEventSource {
listeners : Vec<Box<dyn Handler>>,
...
}
trait Handler { fn handle(ev: &XEvent) -> () }
impl XEventSource {
fn addLisnter(&mut self, listener : Box<dyn Handler>) -> () {
self.listeners.push(listener);
}
fn emit(&self) -> () {
XEvent ev = ...;
for listener in listeners.iter() {
listener.handle(&ev);
}
}
}
みたいに作ると、利用者が好きに作った構造体でもHandlerをimplすればlistenersに足せる
ジェネリクスだとイベントリスナの実際の型1つしかaddできないので不便
404デフォルトの名無しさん
2020/04/06(月) 23:45:59.83ID:TaQVQ6iW >>402
実行時に型を振り分けるとなると仮想関数テーブルを辿る必要があるんで実行時コストが少し増えるよ。
(Rust では仮想関数って言わないのかな? 正確な用語がわからん。)
トレイトを実装している型を実際には一種類しか使わないのだったら、
実行時間を除けば見かけ上の動作で違いはないかもしれんな。
でも基本的にはやりたいことを出来る範囲で制約は厳しい方がいい。
間違いの検出される可能性が高まるから。
制約をどのように表現するかというのはプログラミング言語の設計においては重要なトピックで、
構造化プログラミングが提唱されたのも goto だと制御をどこへ移動するのか制約を付けられないってのがある。
さらにそれを発展させた形として型で制約を付けようってのが色々と考えられてきたし、
Rust では更にオブジェクトの寿命に制約を付けようという考えが実現された。
その関数では何ができるのか、そして「何をしてはいけないのか」ってのを考えると
Rust らしいプログラムが出来ると思う。
実行時に型を振り分けるとなると仮想関数テーブルを辿る必要があるんで実行時コストが少し増えるよ。
(Rust では仮想関数って言わないのかな? 正確な用語がわからん。)
トレイトを実装している型を実際には一種類しか使わないのだったら、
実行時間を除けば見かけ上の動作で違いはないかもしれんな。
でも基本的にはやりたいことを出来る範囲で制約は厳しい方がいい。
間違いの検出される可能性が高まるから。
制約をどのように表現するかというのはプログラミング言語の設計においては重要なトピックで、
構造化プログラミングが提唱されたのも goto だと制御をどこへ移動するのか制約を付けられないってのがある。
さらにそれを発展させた形として型で制約を付けようってのが色々と考えられてきたし、
Rust では更にオブジェクトの寿命に制約を付けようという考えが実現された。
その関数では何ができるのか、そして「何をしてはいけないのか」ってのを考えると
Rust らしいプログラムが出来ると思う。
405デフォルトの名無しさん
2020/04/07(火) 08:14:23.99ID:FPXvnSDp APIサーバーでJSON受け取るときに値の型が違ったりオーバーフローするときってどうしてる?
serde_json::from_str で構造体の属性でエラーメッセージとかつけれたらいいのにな
serde_json::from_str で構造体の属性でエラーメッセージとかつけれたらいいのにな
406デフォルトの名無しさん
2020/04/07(火) 15:06:01.62ID:+YUDNjw9 from_strの結果そのまま使ってるけどダメなの
シンタックスエラーとか含めると大変じゃない
シンタックスエラーとか含めると大変じゃない
407デフォルトの名無しさん
2020/04/07(火) 15:54:15.51ID:FPXvnSDp 海外向けサーバーだったらいいけど日本向けサーバーの場合は?
serde_jsonのエラーメッセージcustomizableじゃないから辛い
serde_jsonのエラーメッセージcustomizableじゃないから辛い
408デフォルトの名無しさん
2020/04/07(火) 16:02:31.28ID:+YUDNjw9 serde_json::Error を見ると行と列と大雑把な原因はとれるみたい
細かくやるなら置換するしかなさそうだね
細かくやるなら置換するしかなさそうだね
409デフォルトの名無しさん
2020/04/08(水) 10:01:13.64ID:qyTF9Er6 reached the configured maximum number of stack frames
でスタックフレームの制限にかかるんだけどオプションとかで変えれる?
でスタックフレームの制限にかかるんだけどオプションとかで変えれる?
410デフォルトの名無しさん
2020/04/11(土) 23:13:20.24ID:EhWtF4tX impl<'_, T> Drop for std::collections::vec_deque::Drain<'_, T>
こういう風にちゃんとパス書かれたのもあれば、デフォルトインポートされてないのに省略されてる型あるけどどうなってるの?
https://doc.rust-lang.org/std/ops/trait.Drop.html
こういう風にちゃんとパス書かれたのもあれば、デフォルトインポートされてないのに省略されてる型あるけどどうなってるの?
https://doc.rust-lang.org/std/ops/trait.Drop.html
411デフォルトの名無しさん
2020/04/11(土) 23:59:49.19ID:Ni1vKiQd フルパス書かなくてもいいように
mod.rsに指定されてるものとされてないもの
mod.rsに指定されてるものとされてないもの
412デフォルトの名無しさん
2020/04/12(日) 23:38:47.63ID:dFThPQBr クロージャの再帰呼び出しってできないんですか?
413デフォルトの名無しさん
2020/04/13(月) 09:02:25.60ID:45YCco/F それが必要な理由は?ここはお前の便利帳じゃねーんだから
有益な使い方が有れば紹介してから聞け
有益な使い方が有れば紹介してから聞け
415デフォルトの名無しさん
2020/04/13(月) 11:59:07.30ID:WFzH9Pd8416デフォルトの名無しさん
2020/04/14(火) 07:17:51.31ID:WrIQImmd Copyでの関数呼び出しとポインタ作成ってコスト的にはプリミティブのどの型からが処理重い?
ここらへんCSの知識ないからわかんない
ここらへんCSの知識ないからわかんない
417デフォルトの名無しさん
2020/04/15(水) 02:35:11.54ID:rawye3jg Rust仕事で使ってる人〜
ウチはコロナの影響でプロジェクト吹き飛んだよん( ;∀;)
ウチはコロナの影響でプロジェクト吹き飛んだよん( ;∀;)
418デフォルトの名無しさん
2020/04/15(水) 02:44:45.60ID:hMxv+37E あらら(´・ω・`)
419デフォルトの名無しさん
2020/04/15(水) 05:30:29.65ID:SZSUFLJC 組み込みで試験的に導入したけどムズイ
まあ慣れの問題もあるのだろうけど
まあ慣れの問題もあるのだろうけど
420デフォルトの名無しさん
2020/04/15(水) 21:10:37.56ID:mcKFmUGe 組み込みでrustに似た言語。ATS2が。
421デフォルトの名無しさん
2020/04/15(水) 21:11:58.85ID:60TKpqE+ Nimは?
422デフォルトの名無しさん
2020/04/15(水) 21:27:25.14ID:8I3eMZIA ATS2ってRust以上にドキュメントが少なくてHaskell以上に難解なアレじゃないですかやだー!
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- ネット殺到「高市総理の責任」「完全に高市リスク」「負けるな」中国が水産物輸入停止→流石に総理批判の声も「どう責任取る?」 ★6 [樽悶★]
- 【🐼🇨🇳】「高市総理VS中国」で日本からパンダはゼロに? 上野動物園「パンダ返還期限」まであと4カ月…★2 [BFU★]
- ネット殺到「高市総理の責任」「完全に高市リスク」「負けるな」中国が水産物輸入停止→流石に総理批判の声も「どう責任取る?」 ★5 [樽悶★]
- 【裁判】山上徹也被告の妹「この人は母のふりをした旧統一教会の信者だと思いました」「でも、母の形をしているから突き放せなかった」 [1ゲットロボ★]
- 【速報】 米大使声明 「日本を支えていく」「中国が威圧的手段に訴えるのは断ち難い悪癖」 [お断り★]
- 「“なり得る”って言っただけだから…」高市早苗“存立危機”答弁後に漏らした本音 ★4 [Hitzeschleier★]
- 【速報】アメリカ「高市総理を支持する。中国の威圧は許せない」 [931948549]
- 小野田紀美大臣「悪いことをする外国人は日本にいない状況をつくる」 [856698234]
- 珍🏡珍
- 【安倍悲報】山上徹也「押し入れに大量のつぼ」 [115996789]
- 外国人「日本の立ちんぼガールやばすぎるwwwwwwwww [977790669]
- 🐻「ぼく、人殺しじゃないクマ!」熊さん、冤罪で4匹も殺される [389326466]
