質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

1回答

1952閲覧

Rust: ThreadでSelfのメソッドを呼び出したい

lattex

総合スコア4

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2022/04/02 11:25

前提

Rust言語のThreadの練習をしています。
そこでSample構造体のメソッドをthread::spawn()で呼び出そうとしたのですが以下のエラーが発生しました

発生している問題・エラーメッセージ

error[E0593]: function is expected to take 0 arguments, but it takes 1 argument --> src\main.rs:28:23 | 19 | fn process1(&self) { | ------------------ takes 1 argument ... 28 | thread::spawn(Self::process1); | ------------- ^^^^^^^^^^^^^^ expected function that takes 0 arguments | | | required by a bound introduced by this call | note: required by a bound in `spawn` --> C:\Users\LatteSyobon\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:620:8 | 620 | F: FnOnce() -> T, | ^^^^^^^^^^^^^ required by this bound in `spawn`

該当のソースコード

Rust

1use std::thread; 2 3fn main() { 4 let s = Sample::new(); 5 s.run(); 6} 7 8pub struct Sample { 9 10} 11 12impl Sample { 13 pub fn new() -> Self { 14 Self { 15 16 } 17 } 18 19 fn process1(&self) { 20 println!("Hello from Process1") 21 } 22 23 fn process2(&self) { 24 println!("Hello from Process2") 25 } 26 27 pub fn run(&self) { 28 thread::spawn(Self::process1); 29 thread::spawn(Self::process2); 30 } 31}

試したこと

引数として&selfを渡すように言われているのはわかるのですが、そこで以下のようにしてみると

Rust

1// ~~~~ 2pub fn run(&self) { 3 thread::spawn(Self::process1(self)); 4 thread::spawn(Self::process2(self)); 5} 6// ~~~~

次は以下のようなエラーが出てしまいます

error[E0277]: expected a `FnOnce<()>` closure, found `()` --> src\main.rs:28:23 | 28 | thread::spawn(Self::process1(self)); | ------------- ^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<()>` closure, found `()` | | | required by a bound introduced by this call | = help: the trait `FnOnce<()>` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` note: required by a bound in `spawn` --> C:\Users\LatteSyobon\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:620:8 | 620 | F: FnOnce() -> T, | ^^^^^^^^^^^^^ required by this bound in `spawn`

この場合どのようにすれば良いのでしょうか?

補足情報(FW/ツールのバージョンなど)

  • Rustc 1.57

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

std::thread::spawn の型をご覧ください。

rust

1pub fn spawn<F, T>(f: F) -> JoinHandle<T> where 2 F: FnOnce() -> T, 3 F: Send + 'static, 4 T: Send + 'static,

このとき引数 f の制約として FnOnce() -> T が期待されており、これは引数がない関数であることを意味しています。

なので、 process1process2 が無引数の関数であれば問題なくコンパイルできます。

rust

1use std::thread; 2 3fn main() { 4 let s = Sample::new(); 5 s.run(); 6} 7 8pub struct Sample { 9 10} 11 12impl Sample { 13 pub fn new() -> Self { 14 Self { 15 16 } 17 } 18 19 fn process1() { 20 println!("Hello from Process1") 21 } 22 23 fn process2() { 24 println!("Hello from Process2") 25 } 26 27 pub fn run(&self) { 28 thread::spawn(Self::process1); 29 thread::spawn(Self::process2); 30 } 31}

その上で、新しく作ったスレッドから self にアクセスしたいのであればチャンネルを通じてメインスレッドと通信する形になるでしょう。 そのあたりのわかりやすい解説は The Rust Programming Language16.2 をご覧ください。 (日本語訳)

投稿2022/04/03 09:18

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lattex

2022/04/03 12:19

ありがとうございました!無事にできました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問