Почему я использую generic в предложении where, но компилятор все равно сообщает, что он не используется?

#rust

Вопрос:

Код:

 struct A<F, T, R> where F: FnOnce(T) -> R {
    foo: F,
}
 

Ошибка:

 error[E0392]: parameter `T` is never used
error[E0392]: parameter `R` is never used
 

Почему я использую generic в предложении where, но компилятор все равно сообщает, что он не используется?

Комментарии:

1. Если вы можете избежать этого, я бы рекомендовал не указывать признак, привязанный к структуре, а скорее к impl. Если у вас есть это в структуре, вам все равно нужно повторять это везде.

Ответ №1:

Это ограничение системы типов, которая в настоящее время проверяет, как выглядит непосредственно используемый тип, а не только как условие между ограничениями.

Решением является использование фантомных типов, которые не требуют затрат времени выполнения:

 use std::marker::PhantomData;

struct A<F, T, R> where F: FnOnce(T) -> R {
    phantom: PhantomData<(T, R)>,
    foo: F,
}
 

Комментарии:

1. или просто _pd: PhantomData<(R, T)>

2. Это заставит средство проверки отбрасывания подумать, что отбрасывание A может привести к отбрасыванию значений типа T и/или R . Чтобы предотвратить это, можно объявить фантомные данные как PhantomData<fn() -> (T, R)> .

3. Или, еще лучше, как PhantomData<fn(T) -> R> , чтобы отклонение не изменилось.