Почему пожизненное избрание не работает на черты - PullRequest
0 голосов
/ 18 января 2020

Я хотел бы создать свою собственную черту, которая должна давать i32 на основе индексации с f32. Я попробовал следующее, которое, кажется, работает:

use std::ops::Index;
// trait by value
pub trait MyTrait:
    Index<f32, Output=i32> {
}

Хотя передача значения f32 может быть хорошей идеей, для более сложных типов я бы вместо этого передал ссылку на значение, поэтому Я попробовал следующее:

// trait by reference, not compiling
pub trait MyTrait:
    Index<&f32, Output=i32> {
}

Включение этого определения дает мне error[E0106]: missing lifetime specifier. У меня работает этот вариант:

// trait by reference, compiling
pub trait MyTrait<'a>:
    Index<&'a f32, Output=i32> {
}

Проблема в том, что, хотя этот подход работает, это означает, что любой тип, реализующий MyTrait, нуждается в явном аргументе времени жизни.

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

struct Test {
  value: i32
}

impl Index<&f32> for Test {
  type Output = i32;

  fn index(&self, _key: &f32) -> &Self::Output {
    &self.value
  }
}

Вопрос 1: Зачем мне нужен дополнительное время жизни в определении признака, почему оно не может быть исключено?

Вопрос 2: Могу ли я определить признак таким образом, чтобы избежать необходимости вводить время жизни?

Ответы [ 2 ]

2 голосов
/ 18 января 2020

Насколько я могу судить (и я не уверен на 100%, в документах об этом ничего не говорится), это:

impl Index<&f32> for Test { /* ... */ }

- сокращение от этого:

impl <'a> Index<&'a f32> for Test { /* ... */ }

Другими словами, вы реализуете черту для любого времени жизни.

Аналогично, вы можете потребовать, чтобы черта была реализована для любого времени жизни в ваших границах:

pub trait MyTrait:
    for<'a> Index<&'a f32, Output = i32> {
  // ...
}
2 голосов
/ 18 января 2020

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

Пожизненное исключение применяется только к подпись функции . Так что нет, это не сработает для вашего определения черты.

Могу ли я определить черту таким образом, чтобы избежать необходимости вводить время жизни?

Конечно, Вы можете использовать параметр generi c так же, как это делает std::ops::Index:

use std::ops::Index;
pub trait MyTrait<T>: Index<T, Output = i32> {}

struct Test {
    value: i32,
}

impl Index<&f32> for Test {
    type Output = i32;

    fn index(&self, _key: &f32) -> &Self::Output {
        &self.value
    }
}

impl MyTrait<&f32> for Test {}
...