公式
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/
探検
Rust part14
■ このスレッドは過去ログ倉庫に格納されています
2022/02/12(土) 01:24:16.59ID:XYE+Rws6
702デフォルトの名無しさん
2022/04/26(火) 23:09:05.06ID:Nz4IrK9J そこまでしてやるメリットが全くない
matchでやるならマッチガード一択
matchでやるならマッチガード一択
703デフォルトの名無しさん
2022/04/26(火) 23:34:34.80ID:sIujHvVn704デフォルトの名無しさん
2022/04/27(水) 04:56:28.33ID:bvfmGeJD うーんRustのコンパイルエラーは素晴らしいな
705デフォルトの名無しさん
2022/04/27(水) 06:27:18.74ID:4nwYgCZM rustのジェネリックでSystemCみたいなのって書ける?
C#だと無理っぽいんだけど
C#だと無理っぽいんだけど
706デフォルトの名無しさん
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]);
はできなかった
#[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]);
はできなかった
707デフォルトの名無しさん
2022/04/27(水) 11:10:01.91ID:zNaA7U6C 演算子 ? のことを個人的にトライ演算子と呼んでいたんですが、
公式には単に「operator ?」としか書いていないみたいですね。
口頭で言うときにはどういう言い方で呼びます?
公式には単に「operator ?」としか書いていないみたいですね。
口頭で言うときにはどういう言い方で呼びます?
708デフォルトの名無しさん
2022/04/27(水) 11:16:36.97ID:2jBbs2Yc https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator
一応公式はquestion mark operatorとのこと
日本語で口頭だと、はてな演算子って言っちゃうかな
一応公式はquestion mark operatorとのこと
日本語で口頭だと、はてな演算子って言っちゃうかな
709デフォルトの名無しさん
2022/04/27(水) 11:26:22.90ID:zNaA7U6C >>708
他は機能で名前が付いているのにそれだけ字面を元にした名前なんですね。
他は機能で名前が付いているのにそれだけ字面を元にした名前なんですね。
710デフォルトの名無しさん
2022/04/27(水) 11:32:02.01ID:Xa5DwGtB try-catchが将来入ることを考えると、 ? の役割は try と言うより throw 相当と考えた方が良いのかな
711デフォルトの名無しさん
2022/04/27(水) 11:42:11.93ID:6hfejJV6 >>709
question markそのものにYes/Noの2択を突きつける意味があるからだろうな
question markそのものにYes/Noの2択を突きつける意味があるからだろうな
712デフォルトの名無しさん
2022/04/27(水) 12:31:18.25ID:QnhXU+83713デフォルトの名無しさん
2022/04/27(水) 13:12:23.42ID:yb/peNBg Cowにmapがほしい
714デフォルトの名無しさん
2022/04/27(水) 13:58:49.07ID:xkktFfcp 前置ならtryのままでもよかったんだろうけどね
715デフォルトの名無しさん
2022/04/27(水) 14:44:12.78ID:mvVxShyZ 後置でメソッドチェーンと相性よくなった
716デフォルトの名無しさん
2022/04/27(水) 15:54:47.56ID:zNaA7U6C 後置にするにしても普通のメソッドみたいになんらかの名前で呼び出すようにしたら
それがプログラムの流れを変える制御構文的なものであることが分かり難くなるだろうし、
後置の演算子という選択はとても良いと思う。
それがプログラムの流れを変える制御構文的なものであることが分かり難くなるだろうし、
後置の演算子という選択はとても良いと思う。
717デフォルトの名無しさん
2022/04/27(水) 16:00:03.30ID:fXEX2s7j718デフォルトの名無しさん
2022/04/27(水) 16:17:57.00ID:QP7+22WQ >>716
後置の演算子にするのはRustの使い方なら当然だと思うが
声に出して読めない(人によって読み方がバラバラになってる)のが問題
try file.read()時代は誰でも同じように読めた
file.read()? は読めない
.awaitはオペレータを導入したとしてもawaitオペレータという呼び方でみんな同じように読めるから何の問題もない
後置の演算子にするのはRustの使い方なら当然だと思うが
声に出して読めない(人によって読み方がバラバラになってる)のが問題
try file.read()時代は誰でも同じように読めた
file.read()? は読めない
.awaitはオペレータを導入したとしてもawaitオペレータという呼び方でみんな同じように読めるから何の問題もない
719デフォルトの名無しさん
2022/04/27(水) 16:26:14.46ID:nimuFt37 file.read().await? よりも
file.read()待? でいいんじゃないかな
オペレータ記号は仮に「待」とした
file.read()待? でいいんじゃないかな
オペレータ記号は仮に「待」とした
720デフォルトの名無しさん
2022/04/27(水) 16:32:03.42ID:Xa5DwGtB 演算子として使える記号残ってる?
721デフォルトの名無しさん
2022/04/27(水) 19:33:26.91ID:quTQsckx722デフォルトの名無しさん
2022/04/27(水) 19:36:30.61ID:Xa5DwGtB Cow::to_mut() じゃだめ?
723デフォルトの名無しさん
2022/04/27(水) 19:42:04.29ID:du++GsRu724デフォルトの名無しさん
2022/04/28(木) 10:44:53.84ID:9IEjG0GC バイナリデータを受け取るいい方法ってある?
やりたいことはGETリクエストの結果送られてくるバイナリデータをファイルに保存したい
CやJavaなら適当なchar配列(Javsはbyte)でいっぱいまで受け取ってファイルに書き出すを繰り返せばいいってわかるんだけど、似たようなことをRustでやりたい
やりたいことはGETリクエストの結果送られてくるバイナリデータをファイルに保存したい
CやJavaなら適当なchar配列(Javsはbyte)でいっぱいまで受け取ってファイルに書き出すを繰り返せばいいってわかるんだけど、似たようなことをRustでやりたい
725デフォルトの名無しさん
2022/04/28(木) 11:03:14.51ID:ZJVxwbem726デフォルトの名無しさん
2022/04/28(木) 11:12:32.29ID:9IEjG0GC ありがとう
やってみる
やってみる
727デフォルトの名無しさん
2022/04/28(木) 11:40:54.23ID:ZJVxwbem 綺麗に抽象化したレイヤを作ろうとしたら C や Java とは違った雰囲気にはなるだろうけど、そういうのは後回しや。
綺麗だろうが汚かろうがまずはやってみたらええんや。
ところで「汚かろう」を変換したら「北中朗」と出てきた。 誰やお前は。
綺麗だろうが汚かろうがまずはやってみたらええんや。
ところで「汚かろう」を変換したら「北中朗」と出てきた。 誰やお前は。
728デフォルトの名無しさん
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
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
729デフォルトの名無しさん
2022/04/30(土) 03:53:42.52ID:cIBooLV/ 16進数文字列から整数への変換を標準ライブラリでやるにはどうすればよいですか?
730デフォルトの名無しさん
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は出ますが
int x = 0x12345678;
char *p = &x;
for( int i = 0; i< sizeof(int); i++ ){
fprintf(stderr, "%X\n", *p++ );
}
CでもWarningは出ますが
731デフォルトの名無しさん
2022/04/30(土) 09:38:22.42ID:2I/Bonq2732デフォルトの名無しさん
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) });
}
}
どうしても表示したいならば
直訳するとこんな感じ
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) });
}
}
733デフォルトの名無しさん
2022/04/30(土) 22:34:14.48ID:jfGNsSDk 原則としてはエンディアンに依存しない形で書いて入出力のときだけ from_le とか to_le とかで処理するのが良い作法だとは思うけどね……。
734デフォルトの名無しさん
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"));
}
仕様がわからないからジェネリックに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"));
}
735デフォルトの名無しさん
2022/04/30(土) 23:19:42.84ID:xinPqoeI736デフォルトの名無しさん
2022/05/01(日) 09:25:29.21ID:WWrQ89FM >>734
がんばりすぎw
がんばりすぎw
737デフォルトの名無しさん
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);
}
use std::usize;
fn main() {
let z = usize::from_str_radix("ffff", 16).unwrap();
assert_eq!(z, 65535);
}
738デフォルトの名無しさん
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()に統一できる
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()に統一できる
739デフォルトの名無しさん
2022/05/01(日) 20:49:11.67ID:4fkon5Y4 u128でもfrom_str_radix使えるのはさておき
便利そうだけどそんなtraitにFromStrという名前が付くのは違和感あるなあ
便利そうだけどそんなtraitにFromStrという名前が付くのは違和感あるなあ
740デフォルトの名無しさん
2022/05/01(日) 21:11:45.93ID:RoZQG5Cx741デフォルトの名無しさん
2022/05/01(日) 21:14:33.66ID:Z7VnuZFm >>740
FromStrなのにSelf以外の型に変換されるのが違和感あるということでは
FromStrなのにSelf以外の型に変換されるのが違和感あるということでは
742デフォルトの名無しさん
2022/05/01(日) 21:15:48.33ID:Z7VnuZFm T::from_str が T (Result<T, E>) 以外の型を返す関数なのは違和感あるでしょってことが言いたかった
743デフォルトの名無しさん
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 と同一になるけど、そこを指定できると互換性を保ったまま利便性を向上できるという話だよね
中身はu128しかないのだから FromStr<Output = u128> で u128 を返せると便利、って話だよね
XXX::from_str の XXX 部分は文字列をどう解釈するかの指定
だから通常は Output = XXX と同一になるけど、そこを指定できると互換性を保ったまま利便性を向上できるという話だよね
744デフォルトの名無しさん
2022/05/01(日) 22:19:59.78ID:Z7VnuZFm 提案自体は分かるけど T from str と読めるメソッドが T 以外の何者かを返すのは不適切な命名では?
別のtraitでやるべきだと思う
別のtraitでやるべきだと思う
745デフォルトの名無しさん
2022/05/01(日) 22:44:03.61ID:4fkon5Y4 >>741
そういうこと
不用意に複雑にするのはよろしくないし、stdにある必要も無いと思う
どうしてもやりたければ↓みたいに自分で実装できるし、
もっと複雑になってきたら適切なパーサライブラリでも使用するのがいいだろう
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f450a3bdf5eab0f1849b4945aede582f
そういうこと
不用意に複雑にするのはよろしくないし、stdにある必要も無いと思う
どうしてもやりたければ↓みたいに自分で実装できるし、
もっと複雑になってきたら適切なパーサライブラリでも使用するのがいいだろう
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f450a3bdf5eab0f1849b4945aede582f
746デフォルトの名無しさん
2022/05/01(日) 23:00:56.52ID:4fkon5Y4 ところでこれ書いてて気づいたけど i8::from_str_radix("80", 16) とかは PosOverflow になるんですね
16 だからできそうな気がするだけで、考えてみればそうかという感じだけど
16 だからできそうな気がするだけで、考えてみればそうかという感じだけど
747デフォルトの名無しさん
2022/05/01(日) 23:26:05.49ID:fn7me9b4748デフォルトの名無しさん
2022/05/02(月) 02:54:31.42ID:9t4339jX749デフォルトの名無しさん
2022/05/02(月) 15:22:57.69ID:mbEFGeje cargo が粗悪
スグにリソースを喰らい尽くす特級禍呪怨霊
スグにリソースを喰らい尽くす特級禍呪怨霊
750デフォルトの名無しさん
2022/05/02(月) 15:33:08.28ID:nqnbrNKO >>749
メモリかCPUが足りないなら -j オプションつけるか
.cargo/config.toml の jobs 設定したら良いのでは
https://doc.rust-lang.org/cargo/reference/config.html
メモリかCPUが足りないなら -j オプションつけるか
.cargo/config.toml の jobs 設定したら良いのでは
https://doc.rust-lang.org/cargo/reference/config.html
751デフォルトの名無しさん
2022/05/02(月) 18:47:44.24ID:G4+2oPiW どちらも参照で構造体のオプションをそのメンバーのオプションにするもっと短い表記ないのかな
struct1.map(|struct1| struct1.member2)
struct1.map(|struct1| struct1.member2)
752デフォルトの名無しさん
2022/05/02(月) 22:42:33.85ID:gA2l3mfi どちらも参照とは?
753デフォルトの名無しさん
2022/05/02(月) 23:24:08.49ID:J2M173NZ メンバーを参照で返すならば
&struct1.member2 と&が必要
元のOptionのstruct1はもし参照が外側ならば
struct1.as_ref() で内側の参照にしておくことが必要
&struct1.member2 と&が必要
元のOptionのstruct1はもし参照が外側ならば
struct1.as_ref() で内側の参照にしておくことが必要
754デフォルトの名無しさん
2022/05/03(火) 01:23:35.68ID:PKeASy9M struct1.map(|struct1| &struct1.member2)
長くていいなら
struct1.and_then(|struct1| Some(&struct1.member2))
長くていいなら
struct1.and_then(|struct1| Some(&struct1.member2))
755デフォルトの名無しさん
2022/05/03(火) 02:02:53.67ID:PFPUtHlZ すごく曖昧な日本語だけど普通に読むなら
構造体のオプションも、そのメンバーのオプションも、どちらも参照という意味じゃないの?
struct Foo<‘a> {
bar: &’a Option<Bar>
}
↑こういう構造体を&Option<Foo>の形で受け取って内包する&Option<Bar>で返したいという話
知らんけど
構造体のオプションも、そのメンバーのオプションも、どちらも参照という意味じゃないの?
struct Foo<‘a> {
bar: &’a Option<Bar>
}
↑こういう構造体を&Option<Foo>の形で受け取って内包する&Option<Bar>で返したいという話
知らんけど
756デフォルトの名無しさん
2022/05/03(火) 02:47:01.44ID:w0rxhNU2 これならstruct1が1回しか出てこなくて短い
(|| Some(&struct1?.member2))()
(|| Some(&struct1?.member2))()
757デフォルトの名無しさん
2022/05/03(火) 08:20:59.49ID:Kk3DPrDK758デフォルトの名無しさん
2022/05/03(火) 09:09:45.26ID:PFPUtHlZ そういうことか
だとmapするのが一番シンプル
$0やitのようなクロージャ用の暗黙的変数はないから明示的に渡すのは必須
struct1.map(|x| x.member2)
だとmapするのが一番シンプル
$0やitのようなクロージャ用の暗黙的変数はないから明示的に渡すのは必須
struct1.map(|x| x.member2)
759デフォルトの名無しさん
2022/05/03(火) 10:14:43.19ID:3fqYzlBO 正解はこれ
try {&struct1?.member2}
try {&struct1?.member2}
760デフォルトの名無しさん
2022/05/03(火) 12:00:16.10ID:4pk6EqdP761デフォルトの名無しさん
2022/05/03(火) 14:05:10.50ID:w+5nyn0Z 複オジ式の無駄打ちクロージャは真似したらダメだぞ
762デフォルトの名無しさん
2022/05/03(火) 15:24:00.08ID:PFPUtHlZ >>760
tryブロックはまだしもクロージャの即時実行は意図を曖昧にするだけだから極力避けたほうがいいと思う
多段で長くなるような処理なら関数化して型を明記しておいたほうが後で楽
クロージャは型推論と外部変数のキャプチャで最初は楽できるんだけどね
tryブロックはまだしもクロージャの即時実行は意図を曖昧にするだけだから極力避けたほうがいいと思う
多段で長くなるような処理なら関数化して型を明記しておいたほうが後で楽
クロージャは型推論と外部変数のキャプチャで最初は楽できるんだけどね
763デフォルトの名無しさん
2022/05/03(火) 16:33:58.30ID:+yoZQWc3 十文字かそこらで終わるレベルならクロージャでも別に悪くはないと思うけどね。
多少の無駄は最適化で消えてなくなるだろうし。
ただ、そう思っていると後からごちゃごちゃ処理が増えてわけわからんようになるのが世の常というものなんや……。
多少の無駄は最適化で消えてなくなるだろうし。
ただ、そう思っていると後からごちゃごちゃ処理が増えてわけわからんようになるのが世の常というものなんや……。
764デフォルトの名無しさん
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
}
}
このクロージャで動いている例で教えてください
クロージャではなく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
}
}
このクロージャで動いている例で教えてください
765デフォルトの名無しさん
2022/05/03(火) 17:13:47.14ID:PFPUtHlZ766デフォルトの名無しさん
2022/05/03(火) 17:16:17.82ID:rLcf0Bao >>765
それ?とクロージャ使ってるやん
それ?とクロージャ使ってるやん
767デフォルトの名無しさん
2022/05/03(火) 17:27:23.29ID:TRGOwhZ/ それは良いクロージャ
768デフォルトの名無しさん
2022/05/03(火) 17:31:47.54ID:8YvdvoC0769デフォルトの名無しさん
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));
// 一貫性もあり分かりやすいクロージャ
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));
770デフォルトの名無しさん
2022/05/03(火) 17:47:34.89ID:pSXVlEs+ どうでもいい
nightly使ってろ
nightly使ってろ
771デフォルトの名無しさん
2022/05/03(火) 18:47:46.49ID:EIDH3Xch 複オジがバカにされて暴れてるw
772デフォルトの名無しさん
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))();
結局クロージャのみとなる
つまり最初の部分だけ特別扱いをやめたことで表記が一貫した
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))();
結局クロージャのみとなる
つまり最初の部分だけ特別扱いをやめたことで表記が一貫した
773デフォルトの名無しさん
2022/05/03(火) 19:50:20.80ID:OPUNSUqX >>762
それは視野が狭すぎる
クロージャ類の即時実行は他のプログラミング言語でも普通に使われる
特にRustではインライン展開されて付加コスト無し
そのため様々なcrateでクロージャの即時実行が使われている
標準ライブラリ内部では先行してtryブロックが有効となったためそちらへ移行した
つまりクロージャの即時実行で書いておけばtryブロックがstableとなった時に移行しやすいメリットもある
それは視野が狭すぎる
クロージャ類の即時実行は他のプログラミング言語でも普通に使われる
特にRustではインライン展開されて付加コスト無し
そのため様々なcrateでクロージャの即時実行が使われている
標準ライブラリ内部では先行してtryブロックが有効となったためそちらへ移行した
つまりクロージャの即時実行で書いておけばtryブロックがstableとなった時に移行しやすいメリットもある
774デフォルトの名無しさん
2022/05/03(火) 22:36:42.91ID:IuH2E3f8 複オジがmapとflatMapを理解してないだけだな
775デフォルトの名無しさん
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になったらそのまま置き換えがベストな方法。
激しいのだと"?"が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になったらそのまま置き換えがベストな方法。
776デフォルトの名無しさん
2022/05/03(火) 23:19:39.02ID:NT1ErZg0 tryっていつ安定版に入るの?
777デフォルトの名無しさん
2022/05/03(火) 23:49:23.79ID:EjxGzJz/ tryはクロージャ代用で困っていないが
GATsとimpl specializationを早く安定化して欲しい
GATsとimpl specializationを早く安定化して欲しい
778デフォルトの名無しさん
2022/05/04(水) 10:04:54.12ID:BCVMJms8 try blockが解決しようとしてる問題を理解すればIIFEの何が問題なのかも分かる
779デフォルトの名無しさん
2022/05/04(水) 19:39:53.08ID:mmwxiGlB Rustで出来るだけダサいプログラム書いてみて
780デフォルトの名無しさん
2022/05/04(水) 20:57:45.43ID:fHWEafFD781デフォルトの名無しさん
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;
}
}
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;
}
}
782デフォルトの名無しさん
2022/05/04(水) 23:33:28.78ID:5IOUV+X2783デフォルトの名無しさん
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
}
あとはマジックナンバーを避けて更に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
}
784デフォルトの名無しさん
2022/05/05(木) 05:24:26.06ID:DUJQpJw8 ダサい例として挙げられていたwhileによるカウントアップが使われているけど
const_forはまだまだ先が長そうね
そのためにはIterator
そのためにはimpl Trait
const_forはまだまだ先が長そうね
そのためにはIterator
そのためにはimpl Trait
785デフォルトの名無しさん
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っぽく使えてるかどうか自信なし
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っぽく使えてるかどうか自信なし
786デフォルトの名無しさん
2022/05/05(木) 09:45:30.02ID:l2X3qjWl forってかなり高度な構文だよなと改めて思う
constで使えるようになるのはかなり先になりそうだな...
constで使えるようになるのはかなり先になりそうだな...
787デフォルトの名無しさん
2022/05/05(木) 09:49:51.56ID:MaGUTczU C++ の constexpr でも for が使えるようになるまでちょっとかかったもんな。
788デフォルトの名無しさん
2022/05/05(木) 12:45:23.13ID:2iJgLsAL 在日ちょんこに尻尾振ってついて行って
レイプされたバカ女の数々
https://uploader.cc/s/9d11h2w9wvh4ju43jicl5t80kyyk4buz8anyyinyvh3tpystxk8mmmj9lejo1rer.mp4
殺されりゃ良かったのに
レイプされたバカ女の数々
https://uploader.cc/s/9d11h2w9wvh4ju43jicl5t80kyyk4buz8anyyinyvh3tpystxk8mmmj9lejo1rer.mp4
殺されりゃ良かったのに
789785
2022/05/05(木) 15:13:48.30ID:ddifXjp/790デフォルトの名無しさん
2022/05/05(木) 17:40:31.65ID:FeY8iOM4 カルビーが12月から全社員を対象にした副業制度を導入。
多様な働き方のさらなる進化を目指す
カルビー「何でもテレワーク」工場視察からゆるい勉強会まで
建設業界の常識を覆す“攻め”の働き方改革【週休3日制】を4月からトライアル導入
残業大幅減でも利益は昨対比2倍に上昇!
労働時間すべて社外勤務OK。トラック業界の“先駆者”が新制度
日野、「副業」許可制度を新設 “経験”広げて本業に生かす
ダイハツが副業容認を本格検討、その狙いと新しい働き方とは?
ダイドーグループ、「副業・副業受け入れ制度」を導入
Afterコロナ時代を生き抜くべく、ダイドードリンコが「自社人材の副業」と
「他社からの副業人材の受入れ」を開始
多様な働き方のさらなる進化を目指す
カルビー「何でもテレワーク」工場視察からゆるい勉強会まで
建設業界の常識を覆す“攻め”の働き方改革【週休3日制】を4月からトライアル導入
残業大幅減でも利益は昨対比2倍に上昇!
労働時間すべて社外勤務OK。トラック業界の“先駆者”が新制度
日野、「副業」許可制度を新設 “経験”広げて本業に生かす
ダイハツが副業容認を本格検討、その狙いと新しい働き方とは?
ダイドーグループ、「副業・副業受け入れ制度」を導入
Afterコロナ時代を生き抜くべく、ダイドードリンコが「自社人材の副業」と
「他社からの副業人材の受入れ」を開始
791デフォルトの名無しさん
2022/05/05(木) 18:08:39.19ID:icOcjj+k ふと思ったんだがそろそろブラウザ上でIDE提供増えないのかなあ
792デフォルトの名無しさん
2022/05/05(木) 20:09:56.60ID:JVFKUq6Q >>789
i32とありジェネリックになりきってないぞ
i32とありジェネリックになりきってないぞ
793デフォルトの名無しさん
2022/05/05(木) 20:31:42.14ID:CLlK/Ylr ジェネリック数値型ガイジ
794デフォルトの名無しさん
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>
みたいな関数を書けないかと思って先に試してみたけど
中でリテラル使って計算してるのが祟って書けなかった
必要に応じて実装してもらえればいいかな?
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>
みたいな関数を書けないかと思って先に試してみたけど
中でリテラル使って計算してるのが祟って書けなかった
795デフォルトの名無しさん
2022/05/05(木) 21:51:56.06ID:KLOlIWxl796デフォルトの名無しさん
2022/05/05(木) 23:39:39.98ID:k+DVpXA+ >>795
stdだとマクロ使ってるケースが多い気がするが
stdだとマクロ使ってるケースが多い気がするが
797デフォルトの名無しさん
2022/05/06(金) 00:00:07.68ID:U1cwKpJU >>796
一般的にジェネリックにするためのトレイト境界となるパーツのトレイトは個別に型列挙してimplする必要がある
そこではマクロが有用
パーツとなるトレイトを利用してプログラミングすれば列挙の必要性がない
一般的にジェネリックにするためのトレイト境界となるパーツのトレイトは個別に型列挙してimplする必要がある
そこではマクロが有用
パーツとなるトレイトを利用してプログラミングすれば列挙の必要性がない
798デフォルトの名無しさん
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 すればメソッド自体は共通化できるかなと思って試みたけどこれをどうにもできなくて困った)
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 すればメソッド自体は共通化できるかなと思って試みたけどこれをどうにもできなくて困った)
799デフォルトの名無しさん
2022/05/06(金) 01:50:09.59ID:cmC85Voz そういう場合はif使いなさい
800デフォルトの名無しさん
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でも動く
その問題も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でも動く
801デフォルトの名無しさん
2022/05/06(金) 11:54:43.12ID:gaqqfXMl でもそれi8では動かないだろ
802デフォルトの名無しさん
2022/05/06(金) 12:16:10.95ID:cmC85Voz ざんね〜ん
f64はStepを実装していないので(1.0)..=(100.0)できませ〜ん
いっけね!
f64はStepを実装していないので(1.0)..=(100.0)できませ〜ん
いっけね!
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 首相官邸前で「戦争あおるな」 台湾有事巡る答弁に抗議 [蚤の市★]
- 高市首相告白「『なめられない服』を選ぶことに数時間を費やしました」「外交交渉でマウント取れる服、買わなくてはいかんかもなぁ」 [ぐれ★]
- 【高市リスク】立民・小西洋之参院議員「高市総理がとんでもない安全保障オンチで外交オンチ」 [ぐれ★]
- 『DOWNTOWN+』会員数50万人突破で見えてきた 松本人志の“月収4ケタ万円”驚愕収入 [阿弥陀ヶ峰★]
- 【赤坂ライブハウス刺傷】逃走していた自衛官の男(43)を殺人未遂の疑いで逮捕 警視庁 被害女性とは知人関係 [Ailuropoda melanoleuca★]
- 【フジ】13年ぶり復活「クイズ$ミリオネア」元日放送決定 挑戦者に菊池風磨&ムロツヨシ、みのもんたさん版傑作選もOA [征夷大将軍★]
- 習近平や王毅などの中共幹部、「高市答弁」に関していまだ一切言及なし。すまんこっから何が起きるの? [271912485]
- 夜勤終わり風呂なう
- 【悲報】「全国の独身男性2000万人に年間120万円の独身税をかけるだけで農家を守って米の値段を半分にできるんだよ」8万高市 [257926174]
- 【悲報】東京都民さん、20過ぎてるのに自転車に乗っててて大炎上wwwwwwwwwwww女「いい歳した男で自転車に乗るのは知的障がい者だけだよ? [483447288]
- 【朗報】Amazonブラックフライデー、神すぎる
- 【悲報】ミスター東大さん、高度な『ずらし』を披露するも愚民には理解されず大炎上wwwwwwwwwwww [455031798]
