Как правильно передать lifetime в trait без PhantomData?

Здравствуйте!
Есть вот такая структура

struct ZeroOrOne<'a, P: Parser<'a>> {
    p: P
}

При компиляции rust ругается, что 'a - “unused parameter”. Но если его убрать, то - “undeclared lifetime”

Решить удалось только с помощью PhantomData

struct ZeroOrOne<'a, P: Parser<'a>> {
    p: P,
    phantom: PhantomData<&'a P>,
}

Но, насколько я понимаю, этот тип нужен не совсем для этого.
Как правильно задать определение этой структуры?

Спасибо.

Вполне себе для этого PhantomData и предназначен. Это один из основных кейсов использования, когда нужно “подвязать” “болтающийся” тайп-параметр или лайфтайм-параметр.

Но, я бы это дело не подвязывал на структуру. Пусть структура будет просто:

struct ZeroOrOne<P> {
    p: P
}

А P: Parser<'a> баунд уже декларируйте в impl'ах, а не на самой struct.

Выражаясь более прямолинейно: bound behaviour, not data.

Если Вы делаете баунды на самой структуре, то их тогда приходится тянуть во все impl'ы для этой структуры, что нехило так бьёт по чистоте кода. Здесь об этом можно тоже почитать.

3 лайка

Спасибо за ссылку! Очень полезный репозиторий.

Кстати, такой подход позволил и избавиться от PhantomData. Спасибо ещё раз.