私はこのコード(playground)を有する:形質の中のジェネリックメソッドが、形質オブジェクトのサイズを必要とするのはなぜですか?
use std::sync::Arc;
pub trait Messenger : Sync + Send {
fn send_embed<F: FnOnce(String) -> String>(&self, u64, &str, f: F)
-> Option<u64> where Self: Sync + Send;
}
struct MyMessenger {
prefix: String,
}
impl MyMessenger {
fn new(s: &str) -> MyMessenger {
MyMessenger { prefix: s.to_owned(), }
}
}
impl Messenger for MyMessenger {
fn send_embed<F: FnOnce(String) -> String>(&self, channel_id: u64, text: &str, f: F) -> Option<u64> {
println!("Trying to send embed: chid={}, text=\"{}\"", channel_id, text);
None
}
}
struct Bot {
messenger: Arc<Messenger>,
}
impl Bot {
fn new() -> Bot {
Bot {
messenger: Arc::new(MyMessenger::new("HELLO")),
}
}
}
fn main() {
let b = Bot::new();
}
Iが多型オブジェクトを作りたいと思った(形質Messenger
と多型実装の1つがMyMessenger
です)。私はそれをコンパイルしようとすると、しかし、私はエラーがあります:私は、私はこのケースでSized
を必要としなければならないことを発見した
error[E0038]: the trait `Messenger` cannot be made into an object
--> <anon>:25:5
|
25 | messenger: Arc<Messenger>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Messenger` cannot be made into an object
|
= note: method `send_embed` has generic type parameters
を、これはそれを解決しません。
fn send_embed<F: FnOnce(String) -> String>(&self, u64, &str, f: F)
-> Option<u64> where Self: Sized + Sync + Send;
をそれからそれは正常にコンパイル:しかし、私は次のように私のsend_embed
方法を変更した場合は
- は、なぜ我々はここで
Sized
が必要なのでしょうか?これは、traitオブジェクトからこのメソッドを使用できない場合、多態性に違反します。 私たちは、実際にはその後、
Arc<Messenger>
からこのメソッドを使用することはできません。fn main() { let b = Bot::new(); b.messenger.send_embed(0u64, "ABRACADABRA", |s| s); }
は与える:
error[E0277]: the trait bound `Messenger + 'static: std::marker::Sized` is not satisfied --> <anon>:37:17 | 37 | b.messenger.send_embed(0u64, "ABRACADABRA", |s| s); | ^^^^^^^^^^ the trait `std::marker::Sized` is not implemented for `Messenger + 'static` | = note: `Messenger + 'static` does not have a constant size known at compile-time
を私はここに完全に立ち往生しています。形質でジェネリックメソッドを使って多形性を使う方法は考えられません。方法はありますか?
これは、[形質の概念に関係していますオブジェクト](http://stackoverflow.com/search?q= [rust] + trait + object)と "オブジェクトの安全性"についてかなり議論されています...しかし、私は良い複製を見つけることができません詳細はこちら –
[この質問](http://stackoverflow.com/questions/34758233/working-with-trait-objects-requiring-sized)への回答が役に立ちます。 – ljedrz
@AleksanderFular遊び場でコードを修正しようとしましたか?あなたが言う前に私がこれを試したので、これは残念なことに私を助けませんでした。そして、あなたのコメントの後に、私はもう一度それを試しました[成功なし](https://play.rust-lang.org/?gist=4ade63728c3ad052f070c0937f0f779d&version=stable&backtrace=0)。 –