Listener
- это признак, поэтому Box<Listener>
- это на самом деле - объект признака, Box<dyn Listener>
- к сожалению, ключевое слово dyn
в настоящее время является необязательным.И Box<dyn Listener>
, и &Mouse
реализуют Deref
со связанным типом Target
, который реализует Listener
.В случае &Mouse
значение deref Target
равно Mouse
, но в случае Box<dyn Listener>
это неизвестный объект dyn Listener
размера неизвестного .
Чтобы собрать всю эту информацию, вы можете написать f
следующим образом:
fn f<T, L>(_listener: &T)
where
T: Deref<Target = L>,
L: Listener + ?Sized
{
}
И вызывать ее из каждой функции следующим образом:
fn fbox(listener: &Box<dyn Listener>) {
f(listener);
}
fn fref<L>(listener: &L)
where
L: Listener
{
f(&listener);
}
Другой, возможно, более простой способ взглянуть на это - отказаться от ограничения Deref
и просто использовать обычные ссылки.Используйте Box::as_ref
, чтобы превратить Box
в ссылку, чтобы вызвать ее.Неограниченное ограничение ?Sized
все еще необходимо для случая объекта черты, и все еще работает, так как значение всегда находится за указателем:
fn fbox(listener: &Box<dyn Listener>) {
f(listener.as_ref());
}
fn fref<L>(listener: &L) where L: Listener {
f(listener);
}
fn f<L>(_listener: &L)
where
L: Listener + ?Sized
{
}