Псевдоним для связанного типа супертрейта - PullRequest
0 голосов
/ 21 мая 2018

У меня есть следующая черта:

use std::ops::Index;

trait Map: Index<<Self as Map>::Key> {
    type Key;
}

Index имеет связанный тип Output.Я семантически хочу этот тип, но мне не нравится имя Output в моем API.Таким образом, я хотел бы добавить псевдоним для этого типа.

Я пробовал это (тот же синтаксис для псевдонимов нормального типа):

trait Map: Index<<Self as Map>::Key> {
    type Key;
    type Value = <Self as Index<Self::Key>>::Output;
}

Однако это приводит к ошибке:

error[E0658]: associated type defaults are unstable (see issue #29661)
 --> src/main.rs:9:9
  |
9 |         type Value = <Self as Index>::Output;
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

С проблема отслеживания Я мог бы понять, что этот синтаксис, очевидно, используется для связанных типов, которые могут быть перезаписаны разработчиками.Но я не хочу, чтобы разработчики перезаписывали этот тип, я всегда хочу Map::Value == Map::Output.

Возможно ли это как-нибудь?

1 Ответ

0 голосов
/ 22 мая 2018

Связанный элемент RFC сообщает:

Параметры типа для признаков могут быть «входами» или «выходами»:

  • Входы.Параметр типа «input» используется для определения того, какой импл использовать.

  • Выходы.Параметр типа «output» однозначно определяется impl, но не играет роли при выборе impl.

RFC также уточняет сопоставление признаков:

  • Обработка всех параметров типов черт как типов ввода и
  • Предоставление связанных типов, которые являются типами вывода.

Из этих описаний ясночто связанный тип по замыслу контролируется impl, поэтому невозможно заблокировать разработчикам перезапись типа.

Обходной путь для получения некоторой формы контроля над разработчиком может состоять в определенииметод по умолчанию, использующий связанный тип, например:

pub trait Map: Index<<Self as Map>::Key> {
    type Key;
    type Value = <Self as Index<<Self as Map>::Key>>::Output;

    #[doc(hidden)]
    fn invalid_operation() -> Option<&'static <Self as Index<<Self as Map>::Key>>::Output> {
        None
    }
}

Теперь для разработчиков больше невозможно просто переопределить тип Value по умолчанию, поскольку метод по умолчанию invalid_operation больше не проверяет тип.

Обратите внимание также на функцию doc(hidden), которая удаляет метод по умолчанию из документов.

Имя скрытого метода может быть выбрано для передачи некоторой информации.ион.Для приведенного выше примера разработчик получает сообщение об ошибке:

 error[E0399]: the following trait items need to be reimplemented as `Value` was overridden: `invalid_operation`

Как вы уже знаете, назначение связанных типов по умолчанию недопустимо в текущей стабильной версии Rust, должна использоваться ночная версия и функция должна бытьвключается с:

#![feature(associated_type_defaults)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...