Contrary to popular belief, it is ok and often preferred to use the ordinary Mutex from the standard library in asynchronous code.
The feature that the async mutex offers over the blocking mutex is the ability to keep it locked across an .await point. This makes the async mutex more expensive than the blocking mutex, so the blocking mutex should be preferred in the cases where it can be used. The primary use case for the async mutex is to provide shared mutable access to IO resources such as a database connection. If the value behind the mutex is just data, it’s usually appropriate to use a blocking mutex such as the one in the standard library or parking_lot.
package hoge
funcfoo()int{return1}type bar struct{
a int}funcnewBar()*bar {return&bar{1}}func(b *bar)inc(){
b.a +=1}
a_test.go
package hoge
import"testing"funcTestFoo(t *testing.T){iffoo()!=1{
t.FailNow()}}funcTestBar(t *testing.T){
v :=newBar()if v.a !=1{
t.FailNow()}
v.inc()if v.a !=2{
t.FailNow()}}
Discussion
ものすごい網羅量で圧倒されました。良質なまとめをありがとうございます!
脚注6番に
とありますが、このコード例であれば
std::sync::Mutexでも問題なく動くかなと思います。また、Mutex in tokio::sync - Rustによると、
ChatGPT訳(ちょっと改変あり)↓
とあるので、今回のコード例のようにロックが.awaitをまたがないケースであれば
std::sync::Mutex(あるいはparking_lot::Mutex) を使うことが望ましいようです。非常に充実した記事をありがとうございました!
Rustはほんの少しだけ書いたことがあるだけだったので忘れたことや知らなかったことも多く、
普段よく書いているGoと比較しながら復習できるので、辞書的にも使えるとてもありがたい資料だと思いました!とても面白かったです…!
いくつか、Go側について少しだけ補足的にコメントさせていただきます!
GoとRustのジェネリクスの違いについて
についてですが、
実は、インラインでinterfaceを書くこともできます。
ただ、「interface elementが一つのみかつ、メソッドではなくtype elementのみが含まれる」ケースで使える省略記法 (
[T string|int]のようなもの) が使えないので、記法としてはやや無骨にはなってしまいますね…。テストの実行について
(基本的にと書かれているので余計かもしれませんが、) 一応、別packageのテストについてはデフォルトで並列に実行されるようです。
デフォルトの並列数は、利用可能なCPU数となります。
参考: https://engineering.mercari.com/blog/entry/how_to_use_t_parallel/
全てのテストをデフォルトで並列に実行するRustの振る舞いが理想的なのは完全に同意です (Goだとそれをデフォルトの挙動にしたら競合しまくるので…)
改めて、非常に参考になる記事をありがとうございました!
@magurotuna
なるほどー
知らなかったです!
ありがとうございます!
脚注を修正しておきました!
@syumai
おお、知らなかったです!
勉強になります
コレも知らなかったです!
ありがとうございます!
諸々追記しておきました!
大変素晴らしい記事ありがとうございます!
Rust がコンパイル時に型ごとのコードを生成しますとあってGoはそうでないように見えますが、
Goもgo shape の後にコード生成されるので実際のアセンブリコードは
それぞれ別のアセンブリに生成されているので同じことだと思います。


(アセンブリの
[]はただの名前に括弧が入っているだけです)自分の理解が間違っているようですが、desgin doc を読んで改めて調べてみます
ありがとうございます!
大変な力作尊敬します。すごい...
一点、表現の問題だとは思いますが、 テストの記述について のところにあった記述が気になりました。
同一ファイル内に書くかどうかは異なりますが、Go でもテストファイルのパッケージ名を同一にすることでプライベートな関数のテストが書ける点、補足できればと。(Go でプライベートな関数のテストが書けないという意味で書かれたわけではないと思いますが、念の為...)
@mythrnr
ありがとうございます!
たしかにパッケージが同じならプライベート関数のテスト書けますね
失念していました!
その旨を追記しました!
秀逸な記事ありがとうございます!
ざっと確認した限りですが、ドキュメントテストについては、GoでもRust相当のことはできるのではないでしょうか?
Goのドキュメントテストの特徴としては
といったところでしょうか。ご参考ください。