Соглашения о границах ржавчины и черт характера (? Sized) - PullRequest
2 голосов
/ 20 сентября 2019

На странице 297 из Programming Rust вы можете найти следующее

impl HashMap<K, V> where K: Eq + Hash
{
  fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
      where K: Borrow<Q>,
            Q: Eq + Hash
}

Я видел это раньше, где ?Sized написано само по себе, а остальные границы чертына другой линии?Это соглашение?Насколько я понимаю, вышесказанное фактически совпадает со следующим?

impl HashMap<K, V> where K: Eq + Hash
{
  fn get<Q>(&self, key: &Q) -> Option<&V>
      where K: Borrow<Q>,
            Q: Eq + Hash + ?Sized
}

Почему ?Sized отделено?Вы можете увидеть это в похожем примере на стр. 295 ,

...
where T: AsRef<U>
      T: ?Sized, U: ?Sized
...

1 Ответ

4 голосов
/ 20 сентября 2019

Это чистое соглашение, и оно не задано в камне, но оно имеет некоторые достоинства.

Специальный синтаксис ?Sized позволяет компилятору удалить эту границу, если она не подходит (при мономорфизме),Таким образом, имеет смысл в некоторой степени разделить его и поместить его в общее определение, а не в предложение where, для удобства чтения и отделить тот факт, что, в отличие от других, он не является строгим, жесткимmarker.

Некоторые библиотеки идут еще дальше и перечисляют все маркеры в общем определении и все признаки в предложении where.

Как указано в комментариях и найдено @PeterHall через журнал коммитов, до ржавчины 1.15, ?Sized был доступен только как требование черты в определении типа. Этот PR изменил это на поведение, которое мы имеем сегодня.

...