公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust
公式ドキュメント
https://www.rust-lang.org/learn
Web上の実行環境
https://play.rust-lang.org
※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/
※次スレは原則>>980が立てること
前スレ
Rust part24
https://mevius.5ch.net/test/read.cgi/tech/1716759686/
ワッチョイスレ
プログラミング言語 Rust 4【ワッチョイ】
https://mevius.5ch.net/test/read.cgi/tech/1514107621/
Rust part25
■ このスレッドは過去ログ倉庫に格納されています
2024/07/31(水) 00:46:26.17ID:DBMWY2QT
188デフォルトの名無しさん
2024/08/13(火) 23:36:10.30ID:Hu5uSedp 複オジに何を言ったところで時間の無駄
そろそろ気付いてね
そろそろ気付いてね
189デフォルトの名無しさん
2024/08/13(火) 23:40:06.70ID:d5oxWZvl 同じところで生まれるものしか取り扱わない場合にFoo<'a, 'b, 'c, 'd, 'e>とする必要はない
そこをFoo<'a>でコンパイルが通る使い方をしているならばFoo<'a>で正しい
どちらかが間違っているという変な考えを捨てよう
そこをFoo<'a>でコンパイルが通る使い方をしているならばFoo<'a>で正しい
どちらかが間違っているという変な考えを捨てよう
190デフォルトの名無しさん
2024/08/13(火) 23:46:03.09ID:vwwzn05u191デフォルトの名無しさん
2024/08/13(火) 23:55:49.36ID:LZM61rZJ >>175
読んだ
大雑把な要約
Rustは非常に素晴らしく成功しているがまだ改善できる点がある
一方で既存の言語には問題があり
他の新言語は社会的賛同が低い
そのため唯一の解決方法はRustをさらに改善に導くことである
そこで具体的な改善案を示す
読んだ
大雑把な要約
Rustは非常に素晴らしく成功しているがまだ改善できる点がある
一方で既存の言語には問題があり
他の新言語は社会的賛同が低い
そのため唯一の解決方法はRustをさらに改善に導くことである
そこで具体的な改善案を示す
192デフォルトの名無しさん
2024/08/14(水) 00:30:36.57ID:gAudIBvM >>187
> >>182の構造体の例も、「普通は」struct Foo<'a, 'b>(&'a str, &'b str);のように分けるべきだろう
> 例外は実際に.0も.1も同じStringの部分列であることを想定しているような、同じlifetimeを持つ参照から作ることが想定されている場合か、他にもあるかもしれんが
これについていえば、必要なのは「構造体は自身よりも寿命の短いデータへの参照を持たない」ことなので、基本的には Foo<'a> だけで済むと思う
fn func() {
let a: String = "foo".to_owned();
{
let b: String = "bar".to_owned();
{
let c = Foo{&a, &b};
}
}
}
これはaとbは違う寿命を持つけど、Fooとしては「c が生きているうちに a と b の寿命が尽きない」ことが保証されてれば良いだけなので、aとbの寿命の区別までは必要まではない
だからメンバーは Foo<'a> の寿命である &'a だけで済むという感じ
自分の認識違いだったらすまん
> >>182の構造体の例も、「普通は」struct Foo<'a, 'b>(&'a str, &'b str);のように分けるべきだろう
> 例外は実際に.0も.1も同じStringの部分列であることを想定しているような、同じlifetimeを持つ参照から作ることが想定されている場合か、他にもあるかもしれんが
これについていえば、必要なのは「構造体は自身よりも寿命の短いデータへの参照を持たない」ことなので、基本的には Foo<'a> だけで済むと思う
fn func() {
let a: String = "foo".to_owned();
{
let b: String = "bar".to_owned();
{
let c = Foo{&a, &b};
}
}
}
これはaとbは違う寿命を持つけど、Fooとしては「c が生きているうちに a と b の寿命が尽きない」ことが保証されてれば良いだけなので、aとbの寿命の区別までは必要まではない
だからメンバーは Foo<'a> の寿命である &'a だけで済むという感じ
自分の認識違いだったらすまん
193デフォルトの名無しさん
2024/08/14(水) 00:42:39.43ID:9bQ7P5cg 働け
194デフォルトの名無しさん
2024/08/14(水) 01:41:38.41ID:trbBeScR >>153
ライブラリが乱立してる点
ライブラリが乱立してる点
195デフォルトの名無しさん
2024/08/14(水) 02:10:03.49ID:/eVAI9ia >>194
まずasync/awaitはRustの標準機能
そして使われるFutureやPollやWakerなど各種はRustのcore標準ライブラリにありno_stdでも使える
asyncランタイムは用途ごとに適したものを自由に作ったり選んだり使える
標準的に使われるものはtokioがダウンロード10倍差で圧勝しており乱立と悩まなくていい
まずasync/awaitはRustの標準機能
そして使われるFutureやPollやWakerなど各種はRustのcore標準ライブラリにありno_stdでも使える
asyncランタイムは用途ごとに適したものを自由に作ったり選んだり使える
標準的に使われるものはtokioがダウンロード10倍差で圧勝しており乱立と悩まなくていい
196デフォルトの名無しさん
2024/08/14(水) 06:30:03.80ID:xnFjuNS8 >>164
ライフタイム注釈が間違っているのにコンパイルが通ってしまい正しく動作しない、というプログラム例を一つでも示せばよいのではないか?
そんな例は存在しないと思う
コンパイルが通ったらそのプログラムでライフタイム注釈は間違っていなくて正しく動作するよ
ライフタイム注釈が間違っているのにコンパイルが通ってしまい正しく動作しない、というプログラム例を一つでも示せばよいのではないか?
そんな例は存在しないと思う
コンパイルが通ったらそのプログラムでライフタイム注釈は間違っていなくて正しく動作するよ
197デフォルトの名無しさん
2024/08/14(水) 09:24:59.76ID:9a/DnTrG 挙げた手降ろせない子どもすごい増えたよな
折り合いつける知能もない
折り合いつける知能もない
198デフォルトの名無しさん
2024/08/14(水) 09:32:09.98ID:92pG5tQ9199デフォルトの名無しさん
2024/08/14(水) 10:02:37.51ID:jTlv+Rl8 Tokioが圧勝しているせいでtokio でしか使えないライブラリが出てきていて、tokioが終わったらRustのasyncもオワる状況
200デフォルトの名無しさん
2024/08/14(水) 10:09:25.77ID:LfKGsMNu tokio以外を考慮してるライブラリの方が少数派だろ
201デフォルトの名無しさん
2024/08/14(水) 10:09:58.25ID:OuxAzukv >>199
GAFMなどIT大手がtokio直接支持してるから不滅だよん
GAFMなどIT大手がtokio直接支持してるから不滅だよん
202デフォルトの名無しさん
2024/08/14(水) 10:12:07.88ID:jTlv+Rl8203デフォルトの名無しさん
2024/08/14(水) 10:21:35.01ID:OuxAzukv Rustに代わりうるプログラミング言語の芽すらないよん
IT大手各社が結束して同じ新言語を支持したのはRustが最初で最後かな~
IT大手各社が結束して同じ新言語を支持したのはRustが最初で最後かな~
204デフォルトの名無しさん
2024/08/14(水) 10:31:23.23ID:LfKGsMNu >>203
zig 1.0待ちだろ
zig 1.0待ちだろ
205デフォルトの名無しさん
2024/08/14(水) 10:45:06.96ID:OuxAzukv Rustより保証してくれることが減ってしまう言語は代わりにならないよん
206デフォルトの名無しさん
2024/08/14(水) 10:50:42.29ID:z6gmNdON 良いか悪いかよりも一貫しているかどうかが寿命を決める。
(いや、及第点程度には良いものである必要はあると思うけど。)
C がよい言語とはとても言えないけど皆が一貫して使ってたから価値あるものとして認められてたわけで。
プログラミング言語も言語だからね。
(いや、及第点程度には良いものである必要はあると思うけど。)
C がよい言語とはとても言えないけど皆が一貫して使ってたから価値あるものとして認められてたわけで。
プログラミング言語も言語だからね。
207デフォルトの名無しさん
2024/08/14(水) 10:51:49.79ID:VXEGQejB >>192
lifetimeって究極的には関数の引数と戻り値の間でのリソースの依存関係を示すものだから
FooのメソッドもFooを引数に取る関数も無いなら、どっちでもいいよとしかならんと思う
そして実際にメソッドや関数を定義するときになったら、別々になっていたほうが一番柔軟に指定できるから、第一選択としては分けておいたほうがいい、というのが俺の直感
>>196
「コンパイルが通ってしまい正しく動作しない、というプログラム」が作れてしまうことを問題にしているのではない
「コンパイルは通って正しく動作もするが、制約が強すぎるために使える状況が過剰に限定される関数」が作れてしまうということを問題にしている
だから前者の例を出すことに意味は無いし、あなたもよく知っている通りそれは実際できないだろう
そして「Rustのライフタイムに関するよくある誤解」5)のnext()は後者の問題を示す例になっている
>>196
trait Iteratorではそうなっていないけど、例のnext()が別のtraitのメソッドfn next<'a>(&'a self) -> Option<&'a u8>として宣言されていれば、実装側はそれに従わざるを得ない、と思ったけど
現実にそんなことが要求されることがあるか、と聞かれるとちょっと微妙かも
lifetimeって究極的には関数の引数と戻り値の間でのリソースの依存関係を示すものだから
FooのメソッドもFooを引数に取る関数も無いなら、どっちでもいいよとしかならんと思う
そして実際にメソッドや関数を定義するときになったら、別々になっていたほうが一番柔軟に指定できるから、第一選択としては分けておいたほうがいい、というのが俺の直感
>>196
「コンパイルが通ってしまい正しく動作しない、というプログラム」が作れてしまうことを問題にしているのではない
「コンパイルは通って正しく動作もするが、制約が強すぎるために使える状況が過剰に限定される関数」が作れてしまうということを問題にしている
だから前者の例を出すことに意味は無いし、あなたもよく知っている通りそれは実際できないだろう
そして「Rustのライフタイムに関するよくある誤解」5)のnext()は後者の問題を示す例になっている
>>196
trait Iteratorではそうなっていないけど、例のnext()が別のtraitのメソッドfn next<'a>(&'a self) -> Option<&'a u8>として宣言されていれば、実装側はそれに従わざるを得ない、と思ったけど
現実にそんなことが要求されることがあるか、と聞かれるとちょっと微妙かも
208デフォルトの名無しさん
2024/08/14(水) 12:46:04.27ID:9gU6ei1I zigは本当に最強
209デフォルトの名無しさん
2024/08/14(水) 13:07:18.24ID:HK0RNQ5P >>174
>> next()を1回呼ぼうが2回呼ぼうが、
Rustではその1回目のnext()の値を保持したまま2回目を使えるかどうかの違いが大きいんだよ
最初の仕様は各々の値が使えれることが確認できればいい仕様になっているね
assert_eq!(Some(&b'1'), bytes.next());
assert_eq!(None, bytes.next());
その次の仕様は1回目の値を持ったまま2回目の値を使える仕様になっているね
let byte_1 = bytes.next();
let byte_2 = bytes.next();
if byte_1 == byte_2 {
// 何かしらの処理
}
つまり拡大された別の仕様となっているわけだよ
そのため最初の仕様ではライフタイムがselfと同じでも全く問題ないけど
次の仕様ではselfと異なるものでないといけなくなる
そこが本質があってどちらの仕様も別のものとして存在しているわけよ
わかりやすく例を挙げて説明すると
次のように&[T]ではなくVec<T>を保持するバージョンに変えてみよう
>> next()を1回呼ぼうが2回呼ぼうが、
Rustではその1回目のnext()の値を保持したまま2回目を使えるかどうかの違いが大きいんだよ
最初の仕様は各々の値が使えれることが確認できればいい仕様になっているね
assert_eq!(Some(&b'1'), bytes.next());
assert_eq!(None, bytes.next());
その次の仕様は1回目の値を持ったまま2回目の値を使える仕様になっているね
let byte_1 = bytes.next();
let byte_2 = bytes.next();
if byte_1 == byte_2 {
// 何かしらの処理
}
つまり拡大された別の仕様となっているわけだよ
そのため最初の仕様ではライフタイムがselfと同じでも全く問題ないけど
次の仕様ではselfと異なるものでないといけなくなる
そこが本質があってどちらの仕様も別のものとして存在しているわけよ
わかりやすく例を挙げて説明すると
次のように&[T]ではなくVec<T>を保持するバージョンに変えてみよう
210デフォルトの名無しさん
2024/08/14(水) 13:08:44.09ID:HK0RNQ5P >>209の続き
相違点以外は元コードと同じ名前と形で書いています
struct ByteIter {
vec: Vec<u8>,
index: usize,
}
impl ByteIter {
fn next(&mut self) -> Option<&u8> {
if self.index >= self.vec.len() {
None
} else {
let byte = &self.vec[self.index];
self.index += 1;
Some(byte)
}
}
}
参照を持たなくなったので一見すると有利になっているように見えるけど
最初の仕様しか満たせなくなってる!
ところがこれはGATを用いたLending Iteratorでは当たり前の仕様なんだよ
つまり制限された間違った仕様というよりは別の仕様と捉えることもできるんじゃないかな
相違点以外は元コードと同じ名前と形で書いています
struct ByteIter {
vec: Vec<u8>,
index: usize,
}
impl ByteIter {
fn next(&mut self) -> Option<&u8> {
if self.index >= self.vec.len() {
None
} else {
let byte = &self.vec[self.index];
self.index += 1;
Some(byte)
}
}
}
参照を持たなくなったので一見すると有利になっているように見えるけど
最初の仕様しか満たせなくなってる!
ところがこれはGATを用いたLending Iteratorでは当たり前の仕様なんだよ
つまり制限された間違った仕様というよりは別の仕様と捉えることもできるんじゃないかな
211デフォルトの名無しさん
2024/08/14(水) 19:39:11.70ID:VXEGQejB >>209-210
「ByteIterはバイトのスライスを繰り返すイテレータです」
「今こうして前のプログラムを見返してみると、明らかに間違っていましたね」
とかの日本語で説明した文章をすべて無視して、コンパイルの通ったRustコードだけを正しいものとして「プログラマの意図」を見出そうとすると、そうなるんだね
どう考えるとそういう結論に至るのかはよく分かった
「ByteIterはバイトのスライスを繰り返すイテレータです」
「今こうして前のプログラムを見返してみると、明らかに間違っていましたね」
とかの日本語で説明した文章をすべて無視して、コンパイルの通ったRustコードだけを正しいものとして「プログラマの意図」を見出そうとすると、そうなるんだね
どう考えるとそういう結論に至るのかはよく分かった
212デフォルトの名無しさん
2024/08/14(水) 19:54:05.99ID:HK0RNQ5P213デフォルトの名無しさん
2024/08/14(水) 20:38:24.97ID:VXEGQejB 日本語を読めば分かるよ
新ネタ無さそうならもう終わりにしとくね
lending iteratorって発想は無かったから、そこだけは面白かったかもね
新ネタ無さそうならもう終わりにしとくね
lending iteratorって発想は無かったから、そこだけは面白かったかもね
214デフォルトの名無しさん
2024/08/14(水) 20:56:34.44ID:HK0RNQ5P >>213
最初のプログラムでイテレータの仕様を満たしており正しく動作していま
すよ
コードに問題はありません
その後に行われようとしているのはイテレータの仕様とは別の
以下を通す新たな仕様を満たすための拡張です
| let byte_1 = bytes.next();
| ----- first mutable borrow occurs here
| let byte_2 = bytes.next();
| ^^^^^ second mutable borrow occurs here
| if byte_1 == byte_2 {
| ------ first borrow later used here
両者を区別できていますか?
最初のプログラムでイテレータの仕様を満たしており正しく動作していま
すよ
コードに問題はありません
その後に行われようとしているのはイテレータの仕様とは別の
以下を通す新たな仕様を満たすための拡張です
| let byte_1 = bytes.next();
| ----- first mutable borrow occurs here
| let byte_2 = bytes.next();
| ^^^^^ second mutable borrow occurs here
| if byte_1 == byte_2 {
| ------ first borrow later used here
両者を区別できていますか?
215デフォルトの名無しさん
2024/08/14(水) 23:52:37.44ID:glbfXLC+ 最初のプログラムは関連型のItemを定義できないからIteratorの仕様を満たせないだろ
type Item = &'a u8;
だと拡張(というか修正)した方のコードになる
「正しい」の意味が噛み合ってないことに気付こう
type Item = &'a u8;
だと拡張(というか修正)した方のコードになる
「正しい」の意味が噛み合ってないことに気付こう
216デフォルトの名無しさん
2024/08/14(水) 23:59:55.13ID:orQgr5Ob 結局>>157の記事は破綻してるんだな
イテレータをstd::iter::Iteratorだけを指す狭い意味に取ると
その記事の最初の&u8をItemにした時点でコンパイルエラーとなるから記事は破綻
イテレータを広い意味にとってその記事の方法でもOKとすると
最初の実装でイテレータとしての機能は満たしていて
それを&'a u8にする必要はなくなり記事は破綻
イテレータをstd::iter::Iteratorだけを指す狭い意味に取ると
その記事の最初の&u8をItemにした時点でコンパイルエラーとなるから記事は破綻
イテレータを広い意味にとってその記事の方法でもOKとすると
最初の実装でイテレータとしての機能は満たしていて
それを&'a u8にする必要はなくなり記事は破綻
217デフォルトの名無しさん
2024/08/15(木) 00:04:11.15ID:JUA9dFMu 「コンパイルが通ったならばライフタイムの記述は正しい」で常に合ってるのに、
それがいかにも間違ってるかのように仕立て装うから矛盾が出てる感じ。
それがいかにも間違ってるかのように仕立て装うから矛盾が出てる感じ。
218デフォルトの名無しさん
2024/08/15(木) 13:27:43.17ID:TpdjcC5K Rustは良い言語だと思うけど
清書用だね
清書用だね
219デフォルトの名無しさん
2024/08/15(木) 14:13:48.29ID:ntgKOifP 他の言語よりバージョン管理(git)の技術が問われる気がする
全体の整合性が求められるから個人開発でもまじめにブランチ使わないとしんどい
全体の整合性が求められるから個人開発でもまじめにブランチ使わないとしんどい
220デフォルトの名無しさん
2024/08/15(木) 14:43:48.85ID:vVr6IPen221デフォルトの名無しさん
2024/08/15(木) 15:14:57.56ID:Q4hz384o Rustはコンパイル通らないと嫌な気持ちになるから整合性が必要
動的言語はバグってても笑えるから整合性は不要
動的言語はバグってても笑えるから整合性は不要
222デフォルトの名無しさん
2024/08/15(木) 15:28:46.91ID:bVAhHZZX >>218
Rustはリファクタリングに適していて
そのプログラムの本質のロジック以外のほとんどのミスをコンパイルエラーにしてくれるから
いきなり書き出し始めていってもなんとかなるよ
同じ機能が出てきた時点でtraitにして重複コードがあればそのprovided methodにするとかね
Rustはリファクタリングに適していて
そのプログラムの本質のロジック以外のほとんどのミスをコンパイルエラーにしてくれるから
いきなり書き出し始めていってもなんとかなるよ
同じ機能が出てきた時点でtraitにして重複コードがあればそのprovided methodにするとかね
223デフォルトの名無しさん
2024/08/15(木) 15:33:22.56ID:ntgKOifP 「全体の整合性が求められるから」は「全体の整合性をコンパイラにチェックされるから」に読み替えてくれ
コンパイル通らないと嫌な気持ちになる以前にテストできないだろw
コンパイル通らないと嫌な気持ちになる以前にテストできないだろw
224デフォルトの名無しさん
2024/08/15(木) 16:10:36.88ID:bOFVyCO2 モノリシックな巨大なコードを作らずにクレイトに分けよう
クレイト毎にコンパイルできる
クレイト毎にコンパイルできる
225デフォルトの名無しさん
2024/08/15(木) 16:13:34.27ID:gPssFbVF 自分だけかもしれないけど、新規にコードを書くとき/リファクタするときにエディタにワーニングが表示された状態になるのが精神的に負荷がかかるんだよね
だから新しく作ったファイルの先頭でまず #![allow(dead_code)] するね…
(ある程度コードができてきたら取り払うけど)
だから新しく作ったファイルの先頭でまず #![allow(dead_code)] するね…
(ある程度コードができてきたら取り払うけど)
226デフォルトの名無しさん
2024/08/15(木) 16:23:19.81ID:gPssFbVF >>218
分野によってはそう思う
探索的なデータ分析をするとか画像処理のアルゴリズムを考えるとか、そういう場面だとPython等で試してからRust等に移植というのは分かる
「書いて捨てる」を前提にするにはRustはやや重い
分野によってはそう思う
探索的なデータ分析をするとか画像処理のアルゴリズムを考えるとか、そういう場面だとPython等で試してからRust等に移植というのは分かる
「書いて捨てる」を前提にするにはRustはやや重い
227デフォルトの名無しさん
2024/08/15(木) 16:53:43.32ID:afsyCbP1 それはPythonに慣れてるだけじゃないか?
Python使ったことない人でもそうなるわけではない
Python使ったことない人でもそうなるわけではない
228デフォルトの名無しさん
2024/08/15(木) 17:04:07.16ID:WFExrDMY コンパイルワーニングやエラーが負荷になる人は動的言語でのテストファーストな開発も負荷になりそうだね。
229デフォルトの名無しさん
2024/08/15(木) 17:18:57.30ID:gPssFbVF 慣れというのは否定しないけど、そもそもコンパイル必要な言語とそうでない言語の違いだな
コード書いて Ctrl + S で保存すればすぐに変更後の動作を試せるのは大きい
特にRustなんてコンパイル時間長いんだし
書き捨てる前提の実験的なコードで完璧を目指すものでもないでしょ
コード書いて Ctrl + S で保存すればすぐに変更後の動作を試せるのは大きい
特にRustなんてコンパイル時間長いんだし
書き捨てる前提の実験的なコードで完璧を目指すものでもないでしょ
230デフォルトの名無しさん
2024/08/15(木) 17:31:23.55ID:2Mk02GNe そんなにコンパイル言語が嫌いなら使うな
このスレから永久に出ていけ
このスレから永久に出ていけ
231デフォルトの名無しさん
2024/08/15(木) 17:40:55.12ID:gPssFbVF 自分は用途によっては他の言語も使うとしか書いてないんだが
宗教的あるいは能力的に一つの言語しか使えないんです?
宗教的あるいは能力的に一つの言語しか使えないんです?
232デフォルトの名無しさん
2024/08/15(木) 17:53:40.88ID:KHsgBa/H 特性の真逆なスクリプト言語と比較しても既知の話ばかりで新たな知見も情報も得られないからなあ
ノイズとなるだけのスクリプト言語との比較の話は禁止しようぜ
やりたい人は別スレを立ててやればいい
ノイズとなるだけのスクリプト言語との比較の話は禁止しようぜ
やりたい人は別スレを立ててやればいい
233デフォルトの名無しさん
2024/08/15(木) 18:21:12.60ID:gPssFbVF 自分が言いたかったのは「Rustは清書用」というレスへの同意だけなんだよな
特定の言語を推したり比較したりしたいわけではなく
これ以上の話はスレチになりそうだからやめとく
特定の言語を推したり比較したりしたいわけではなく
これ以上の話はスレチになりそうだからやめとく
234デフォルトの名無しさん
2024/08/15(木) 18:25:33.11ID:IG6WI0D2 俺はRustの方が慣れてるため最初からRust使うので慣れの問題だと思う
235デフォルトの名無しさん
2024/08/15(木) 18:46:44.09ID:OZNxhJTv スクリプト言語で下書きするっていっても直和型もないような言語だと
Rustで清書するときにデータ構造からやり直しだし
どういう言語を想定してるんだろ
TSとか?
Rustで清書するときにデータ構造からやり直しだし
どういう言語を想定してるんだろ
TSとか?
236デフォルトの名無しさん
2024/08/15(木) 18:58:18.84ID:OZNxhJTv 画像処理みたいな純粋なアルゴリズムの検討ならあまりそういう問題はないだろうけど
単なる数値計算なら別に最初からRustでいいと思うんだよな
DLみたいに既存のフレームワーク使うためにPythonで検討したいとかなら分かるんだけど
単なる数値計算なら別に最初からRustでいいと思うんだよな
DLみたいに既存のフレームワーク使うためにPythonで検討したいとかなら分かるんだけど
237デフォルトの名無しさん
2024/08/15(木) 18:59:39.70ID:gPssFbVF アプリ全体の設計レベルだと流石に下書きなんてしないと思う
あくまでも部分的な話で、例えば画像処理なんかだと整数または小数型の多次元配列だけ扱えれば良いので
あくまでも部分的な話で、例えば画像処理なんかだと整数または小数型の多次元配列だけ扱えれば良いので
238デフォルトの名無しさん
2024/08/15(木) 19:32:04.42ID:+y/e/IpZ RustやC++で書かれたライブラリを呼び出すだけの話ならばどの言語でも同じだから議論の意味ない
そうではなく自分でプログラムを組んで実行するなら最初からRustで書けば高速実行できる
そうではなく自分でプログラムを組んで実行するなら最初からRustで書けば高速実行できる
239デフォルトの名無しさん
2024/08/15(木) 20:01:33.38ID:mLyUPHca 実験的な変更の波及範囲が広いんだよね
エラーの種類を増やすためにenum ErrorKindに新しい要素を追加したらErrorKindをmatchで網羅してるDisplayの修正も必要になるとか
最終的には必要な変更だから修正漏れを防ぐ意味では助かるけど一時的な変更だとちょっと大変
バージョン管理が適当だと戻すのも面倒になる
エラーの種類を増やすためにenum ErrorKindに新しい要素を追加したらErrorKindをmatchで網羅してるDisplayの修正も必要になるとか
最終的には必要な変更だから修正漏れを防ぐ意味では助かるけど一時的な変更だとちょっと大変
バージョン管理が適当だと戻すのも面倒になる
240デフォルトの名無しさん
2024/08/15(木) 20:17:28.56ID:cCrv94Lj >>239
thiserrorを使いなさい
thiserrorを使いなさい
241デフォルトの名無しさん
2024/08/15(木) 22:15:21.69ID:nyOB87vc 不満を言う人は単なる不慣れとそれによる知識不足という感じですねー
242デフォルトの名無しさん
2024/08/15(木) 22:23:50.08ID:J+lHdaYT 慣れてくるとサボり方も分かってくるからあまり困らんよね
とりあえずunwrapやtodo!多用してメインのパスだけ作ってしまうみたいなのはよくやる
とりあえずunwrapやtodo!多用してメインのパスだけ作ってしまうみたいなのはよくやる
243デフォルトの名無しさん
2024/08/16(金) 01:41:31.76ID:n83uLnGm で、Rustのコンパイル時間は改善されてるのかい?
244デフォルトの名無しさん
2024/08/16(金) 08:44:44.18ID:AlUb7wqr >>242
あとはclone連打したりBoxに入れたり
あとはclone連打したりBoxに入れたり
245デフォルトの名無しさん
2024/08/16(金) 11:16:32.52ID:NCq9ClXr cargo build とかで rustc にオプションを渡すにはどうすれば良いですか
特定の hoge.rs に対してだけ出来ると有難いです
特定の hoge.rs に対してだけ出来ると有難いです
246デフォルトの名無しさん
2024/08/16(金) 11:33:25.98ID:aaHau8VO clone減らしても結局処理速度変わらなかったりする
247デフォルトの名無しさん
2024/08/16(金) 11:41:08.16ID:ig7l4HYj >>245
cargo rustcかRUSTFLAGS
cargo rustcかRUSTFLAGS
248デフォルトの名無しさん
2024/08/16(金) 13:42:33.29ID:PUHP0I+b >>244
おまえらのために作ったった
// お手軽グローバル変数キット
#[macro_use]
mod x {
pub struct X<T>(pub std::sync::LazyLock<std::sync::Mutex<T>>);
#[macro_export]
macro_rules! x_init { ($x:expr) => { X(std::sync::LazyLock::new(|| std::sync::Mutex::new($x))) } }
#[macro_export]
macro_rules! x { ($x:ident) => (*($x.0.lock().unwrap())) }
}
use x::X;
// グローバル変数の宣言の仕方
static FOO: X<i32> = x_init!(999);
static BAR: X<Vec<i32>> = x_init!(vec![1, 2, 3]);
// グローバル変数の使い方
fn main_() {
x!(FOO) += 1;
assert_eq!(x!(FOO), 1000);
x!(BAR).push(777);
assert_eq!(x!(BAR), [1, 2, 3, 777]);
}
おまえらのために作ったった
// お手軽グローバル変数キット
#[macro_use]
mod x {
pub struct X<T>(pub std::sync::LazyLock<std::sync::Mutex<T>>);
#[macro_export]
macro_rules! x_init { ($x:expr) => { X(std::sync::LazyLock::new(|| std::sync::Mutex::new($x))) } }
#[macro_export]
macro_rules! x { ($x:ident) => (*($x.0.lock().unwrap())) }
}
use x::X;
// グローバル変数の宣言の仕方
static FOO: X<i32> = x_init!(999);
static BAR: X<Vec<i32>> = x_init!(vec![1, 2, 3]);
// グローバル変数の使い方
fn main_() {
x!(FOO) += 1;
assert_eq!(x!(FOO), 1000);
x!(BAR).push(777);
assert_eq!(x!(BAR), [1, 2, 3, 777]);
}
249デフォルトの名無しさん
2024/08/16(金) 14:04:22.59ID:l1JK1BDI 純粋な質問だけどマクロ使わずにできる?
以下のような感じに
static x: X<中身の型> = X::new(初期化式);
assert_eq!(&x, 中身の型と比較可能な値);
x.do_something(); // メソッド呼び出し
以下のような感じに
static x: X<中身の型> = X::new(初期化式);
assert_eq!(&x, 中身の型と比較可能な値);
x.do_something(); // メソッド呼び出し
250デフォルトの名無しさん
2024/08/16(金) 14:20:39.96ID:PUHP0I+b >>249
Mutexへの参照を持つMutexGuardを持つスコープ内でしかDerefできない
つまりメソッドを定義してDerefした結果の参照を返すのは無理
この仕組みにより参照をスコープ外へ持ち出せなくしていることが肝
ただしMutexGuardを返すメソッドは実現できる
その場合は自分でDerefして使うことになる
それにより具体的には *Foo.x() += 1; として使うメソッドx(&self)は実現可能
Mutexへの参照を持つMutexGuardを持つスコープ内でしかDerefできない
つまりメソッドを定義してDerefした結果の参照を返すのは無理
この仕組みにより参照をスコープ外へ持ち出せなくしていることが肝
ただしMutexGuardを返すメソッドは実現できる
その場合は自分でDerefして使うことになる
それにより具体的には *Foo.x() += 1; として使うメソッドx(&self)は実現可能
251デフォルトの名無しさん
2024/08/16(金) 14:28:26.26ID:2XNA/Shu >>249
それだけならできるよ
それだけならできるよ
252デフォルトの名無しさん
2024/08/16(金) 14:28:39.39ID:aaHau8VO >>248
こんなのZigならcomptime付ければ解決だろ
こんなのZigならcomptime付ければ解決だろ
253デフォルトの名無しさん
2024/08/16(金) 14:43:23.29ID:/FTYasP4 >>252
グローバル変数、すなわち、タスクやスレッドが排他制御して安全に扱える話をしているところで、comptime??
グローバル変数、すなわち、タスクやスレッドが排他制御して安全に扱える話をしているところで、comptime??
254デフォルトの名無しさん
2024/08/16(金) 15:12:00.16ID:l1JK1BDI Rustでもコンパイル時に作れるものは簡単にグローバルな定数にできる
問題なのは HashMap みたいなヒープを使うもので、LazyLockが必要になるのもほぼこのようなもののためだと思う
初期化した以降は不変な操作しかしない定数のような使い方をする場合でもMutexが必要なのは仕方ないという感じなのか
問題なのは HashMap みたいなヒープを使うもので、LazyLockが必要になるのもほぼこのようなもののためだと思う
初期化した以降は不変な操作しかしない定数のような使い方をする場合でもMutexが必要なのは仕方ないという感じなのか
255デフォルトの名無しさん
2024/08/16(金) 15:14:27.12ID:l1JK1BDI256デフォルトの名無しさん
2024/08/16(金) 15:20:06.84ID:PUHP0I+b >>254
読み出しだけならMutexは不要
static READ_ONLY: LazyLock<Vec<i32>> = LazyLock::new(|| vec![1, 2, 3]);
assert_eq!(*READ_ONLY, [1, 2, 3]);
読み出しだけならMutexは不要
static READ_ONLY: LazyLock<Vec<i32>> = LazyLock::new(|| vec![1, 2, 3]);
assert_eq!(*READ_ONLY, [1, 2, 3]);
257デフォルトの名無しさん
2024/08/16(金) 17:40:52.16ID:n/S+hvuh LazyLockは油断するとデッドロックの要因になりそうだな
初期化が単純なうちはいいけど
初期化が単純なうちはいいけど
258デフォルトの名無しさん
2024/08/16(金) 18:31:48.52ID:/FTYasP4 LazyLockは排他制御をRust1.0からあるstd::sys::Onceに任せている
その部分はOS依存だが例えばLinuxなどの場合、
未初期化か初期化中か初期化済かなどの状態を示すatomic整数で管理している
そして初期化実行は最初のスレッドのみで起きてそこでの競合は起きないことを保証している
一方で、あるLazyLock利用変数Aの初期化関数で資源Xを利用している時に、
資源Xをロックしたままの状態でその変数Aに最初にアクセスすればデッドロックとなりうる
これは一般的な話と同じなので今回特有の問題ではない
いわゆる資源ロック優先順序付けをA>Xとするだけで回避できる
ちなみに、LazyLock初期化後のT読み出し追加コストはその状態整数を見ることだけになり、
「初期化済」状態でずっと変わらないため分岐予測もおそらくずっと成功
そのためコストは気にせずに使える
その部分はOS依存だが例えばLinuxなどの場合、
未初期化か初期化中か初期化済かなどの状態を示すatomic整数で管理している
そして初期化実行は最初のスレッドのみで起きてそこでの競合は起きないことを保証している
一方で、あるLazyLock利用変数Aの初期化関数で資源Xを利用している時に、
資源Xをロックしたままの状態でその変数Aに最初にアクセスすればデッドロックとなりうる
これは一般的な話と同じなので今回特有の問題ではない
いわゆる資源ロック優先順序付けをA>Xとするだけで回避できる
ちなみに、LazyLock初期化後のT読み出し追加コストはその状態整数を見ることだけになり、
「初期化済」状態でずっと変わらないため分岐予測もおそらくずっと成功
そのためコストは気にせずに使える
259デフォルトの名無しさん
2024/08/17(土) 01:30:12.83ID:OMSBWIoV 小さなTauri v1アプリをv2 RCにアップグレードしたら
リリースビルドのファイルサイズが2倍になったんだが
ファイルサイズ小さいのが売りじゃなかったのか?
6MBが12MBになったぞ
リリースビルドのファイルサイズが2倍になったんだが
ファイルサイズ小さいのが売りじゃなかったのか?
6MBが12MBになったぞ
260デフォルトの名無しさん
2024/08/17(土) 13:50:23.56ID:kywszD5m TauriのことはJavaScript/TypeScriptスレでやれよ
261デフォルトの名無しさん
2024/08/17(土) 14:00:58.13ID:w43wc/GB >>260
Rust のバイナリにリンクする部分は Rust の話じゃね?
Rust のバイナリにリンクする部分は Rust の話じゃね?
262デフォルトの名無しさん
2024/08/17(土) 14:22:14.92ID:wXTvB1/z もしRustやRustの汎用ライブラリのバージョンを変えてバイナリサイズが増えたのならRustの話なのでここでやればいい
しかしアプリのバージョンを変えてサイズが増えたのだからアプリの話であってRustスレで語ることはなにもない
しかしアプリのバージョンを変えてサイズが増えたのだからアプリの話であってRustスレで語ることはなにもない
263デフォルトの名無しさん
2024/08/17(土) 14:27:21.91ID:OMSBWIoV もしかしてTauriがRustのライブラリだと知らない人?
264デフォルトの名無しさん
2024/08/17(土) 14:30:56.85ID:G1OfNx36 Rustに問題があると読めそうな文章なら手段を選ばずに排除する人
265デフォルトの名無しさん
2024/08/17(土) 15:23:05.55ID:Qf5pJUWp rustコードをコンパイルしたwasmバイナリが増えたってこと?
266デフォルトの名無しさん
2024/08/17(土) 15:45:50.91ID:EpylkaBR >>265
Tauriは各OSの他のアプリと同様に各ネイティブで動作するためwasmは関係ない
TauriはWebブラウザと同じ立場なので同様にJavaScriptとwasmが使えるが
そこでのwasmのコードはどのWebブラウザやTauriからも独立していて関係がない
Tauriは各OSの他のアプリと同様に各ネイティブで動作するためwasmは関係ない
TauriはWebブラウザと同じ立場なので同様にJavaScriptとwasmが使えるが
そこでのwasmのコードはどのWebブラウザやTauriからも独立していて関係がない
267デフォルトの名無しさん
2024/08/17(土) 15:53:49.31ID:bT3U9dm8 tauriはネイティブ部分とwebviewでプロセス間通信させて動いてるんだっけか
268デフォルトの名無しさん
2024/08/17(土) 15:55:16.69ID:w43wc/GB tauri は基本的にはその環境にあるウェブコントロールを使う。
生成される実行ファイルにリンクされるのは外部のウェブコントロールとの橋渡しに過ぎないからそんなに大きくないはずなのに……なんで?
っていう話。
生成される実行ファイルにリンクされるのは外部のウェブコントロールとの橋渡しに過ぎないからそんなに大きくないはずなのに……なんで?
っていう話。
269デフォルトの名無しさん
2024/08/17(土) 16:01:00.63ID:zPjNywzn tauriは糞
270デフォルトの名無しさん
2024/08/17(土) 16:05:04.51ID:K84lbgy4 TauriはGUI以外のロジックをTS/JS側で書くかRust側で書くかみたいな話もあるよな
271デフォルトの名無しさん
2024/08/17(土) 16:32:34.13ID:b7Mo3s6c >>268
ウェブコントロールなんて分かりづらい言葉を使わずにWebViewと言ってくれ
ウェブコントロールなんて分かりづらい言葉を使わずにWebViewと言ってくれ
272デフォルトの名無しさん
2024/08/17(土) 16:36:42.10ID:dIGhUzjt >>261
numpyのバージョン上げたら動かなくなったなどと言ってpythonやnumpyのスレではなくCのスレに乗り込んでるようなもんだぞ
numpyのバージョン上げたら動かなくなったなどと言ってpythonやnumpyのスレではなくCのスレに乗り込んでるようなもんだぞ
273デフォルトの名無しさん
2024/08/17(土) 16:47:26.11ID:YqZ4otqM https://tauri.app/v1/guides/building/app-size/
Tauri v1のページだけど、ここに書いてある手法自体はたぶんv2でも有効だから比較調査してみるとよし
Tauri v1のページだけど、ここに書いてある手法自体はたぶんv2でも有効だから比較調査してみるとよし
274デフォルトの名無しさん
2024/08/17(土) 16:50:47.17ID:K84lbgy4 >>272
TauriはRust部分もちゃんと使うフレームワークだぞ
アプリとして必要な処理をRustで書いてそれをJS/TSから呼んだり、データをRust側とフロント側で受け渡したりできる
ほぼTS/JSだけで書くこともできるけど、逆にUI以外のロジックはRustをメインに書くといった使い方もできる
実際のプロジェクトでどう使われてるのかは自分も知らないけど
TauriはRust部分もちゃんと使うフレームワークだぞ
アプリとして必要な処理をRustで書いてそれをJS/TSから呼んだり、データをRust側とフロント側で受け渡したりできる
ほぼTS/JSだけで書くこともできるけど、逆にUI以外のロジックはRustをメインに書くといった使い方もできる
実際のプロジェクトでどう使われてるのかは自分も知らないけど
275デフォルトの名無しさん
2024/08/17(土) 16:53:38.16ID:bEXpluCi 一般的にバイナリサイズは動的リンクの共有ライブラリの使用が多ければその分だけ小さくなり逆は大きくなる
だからバイナリサイズとプログラム全体のサイズは関係がない
そのver.1とver.2でバイナリに含まれていないライブラリの変化を調べて違いを投稿してください
だからバイナリサイズとプログラム全体のサイズは関係がない
そのver.1とver.2でバイナリに含まれていないライブラリの変化を調べて違いを投稿してください
276デフォルトの名無しさん
2024/08/17(土) 16:55:44.18ID:K84lbgy4 ビルドはCargoを使うし、「生成されたバイナリが大きい」みたいな問題もRustのカテゴリーで良い思う
フロント側に使ってるReactやVueについての質問ならJS/TSスレで聞くべきだけど
フロント側に使ってるReactやVueについての質問ならJS/TSスレで聞くべきだけど
277デフォルトの名無しさん
2024/08/17(土) 17:04:38.57ID:tGKWZUAz >「生成されたバイナリが大きい」みたいな問題もRustのカテゴリーで良い思う
意味わからんわwww
意味わからんわwww
278デフォルトの名無しさん
2024/08/17(土) 17:19:21.92ID:K84lbgy4 解決するかはともかく、質問先としてはJavascriptスレよりはRustスレの方が回答してもらえる可能性が高いじゃん
公式のリポジトリのissue見ろって話になるかもしれないけど
公式のリポジトリのissue見ろって話になるかもしれないけど
279デフォルトの名無しさん
2024/08/17(土) 17:24:48.12ID:K84lbgy4 >>259のレスを見落としてるせいでバイナリサイズの話が唐突な話に見えてるのだったらすまん
280デフォルトの名無しさん
2024/08/17(土) 17:35:27.19ID:bEXpluCi まずは動的リンクしているライブラリの変化を調べなよ
例えばもしそれが減ってるなら
依存していた外部ライブラリの不自由さから解放されて状況が良くなっている話の可能性もある
例えばもしそれが減ってるなら
依存していた外部ライブラリの不自由さから解放されて状況が良くなっている話の可能性もある
281デフォルトの名無しさん
2024/08/17(土) 17:40:36.43ID:SISNcxTZ 普通にissueで報告したらええやん
Rustのバージョンもビルド方法もビルドオプションも変えてないんやろ?
Rustのバージョンもビルド方法もビルドオプションも変えてないんやろ?
282デフォルトの名無しさん
2024/08/17(土) 17:47:51.42ID:co5P0ZaQ283デフォルトの名無しさん
2024/08/17(土) 18:16:28.63ID:OMSBWIoV 試しにTauri v1とv2-RCのscaffold同士で比較してみる
共にWindows 11のrustc 1.80.1 (x86_64-pc-windows-msvc)で
フロントエンドはnpm/Vanilla/TypeScriptを選択する
# v1
cargo create-tauri-app
npm run tauri build
src-tauri\target\release\v1-test.exe 5,271 KB
# v2
cargo create-tauri-app --rc
npm run tauri build
src-tauri\target\release\v2rc-test.exe 10,076 KB
やっぱりv2の方が2倍ぐらい大きいんじゃないの?
共にWindows 11のrustc 1.80.1 (x86_64-pc-windows-msvc)で
フロントエンドはnpm/Vanilla/TypeScriptを選択する
# v1
cargo create-tauri-app
npm run tauri build
src-tauri\target\release\v1-test.exe 5,271 KB
# v2
cargo create-tauri-app --rc
npm run tauri build
src-tauri\target\release\v2rc-test.exe 10,076 KB
やっぱりv2の方が2倍ぐらい大きいんじゃないの?
284デフォルトの名無しさん
2024/08/17(土) 18:41:27.25ID:I1dGWckH 今も小さい方のバイナリも生成できていることから
Rustとは無関係な話であると切り分けできてよかったね
Rustとは無関係な話であると切り分けできてよかったね
285デフォルトの名無しさん
2024/08/17(土) 18:46:42.10ID:AaqttF5e tauriのことはjavascriptの範囲 (キリッ)
って書いてたやつが的外れなのは変わらない
って書いてたやつが的外れなのは変わらない
286デフォルトの名無しさん
2024/08/17(土) 19:34:46.59ID:w2zHmV9M 全部issueで聞くべきなのでこのスレは存在意義がないんだよね
287デフォルトの名無しさん
2024/08/17(土) 21:17:58.40ID:WUwor7aX tauri2で
cargo tauri android init
cargo tauri android dev
ってやったらエミュレーターでスプラッシュ画面までは出るんだけど
コンテンツのところで↓みたいなエラーになるんだけど試した人いる?
error sending request for url
(http://127.0.01:1430/)
cargo tauri android init
cargo tauri android dev
ってやったらエミュレーターでスプラッシュ画面までは出るんだけど
コンテンツのところで↓みたいなエラーになるんだけど試した人いる?
error sending request for url
(http://127.0.01:1430/)
■ このスレッドは過去ログ倉庫に格納されています
ニュース
