Rust: определить, когда «параметры неограниченного типа» могут быть явно предоставлены для вызова fn

Созданный на 21 февр. 2017  ·  3Комментарии  ·  Источник: rust-lang/rust

Опираясь на https://github.com/rust-lang/rust/pull/39361 , мы могли бы рассмотреть, когда пользователям следует добавлять явные параметры типа в вызов fn. Я представляю такой пример:

fn foo<T>() { }

fn main() {
    foo();
}

Было бы неплохо предложить пользователю написать foo::<T> вместо некоторого явного T . Это потребует немного размышлений:

Когда мы хотим предложить это вместо аннотирования локальной переменной? Я бы предпочел прикрепить аннотацию к локальной переменной, но, возможно, нет, если тип локальной переменной представляет собой какую-то сложную вещь, которая упоминает невыведенный тип глубоко внутри нее, тогда как аннотирование функции позволило бы нам указать невыведенный тип напрямую .

Пример:

fn foo<T>() -> Option<T> { }

fn main() {
    let x = foo();
}

Должны ли мы предлагать маркировку x: Option<T> или foo::<T> ? Это пограничный случай, но если вы замените Option каким-то более сложным типом, баланс еще больше сместится.

Что мы делаем, когда fn принимает много типов, и мы знаем их частично? Ранее мы обошли проблему того, что делать, когда у нас есть некоторая информация, но не вся. Но такое ощущение, что здесь это может быть важнее. Пример:

fn foo<T, U>() -> T { }

fn main() {
    let x: i32 = foo();
}

Здесь мы знаем T , но не U . Должны ли мы предложить foo::<_, XXX> ? Как сформулировать XXX , чтобы показать пользователю, что это именно то, что ему нужно предоставить?

cc @cengizIO -- интересно продолжать?

cc @estebank @jonathandturner -- мысли о том, как сформулировать?

A-diagnostics C-enhancement E-needs-mentor T-compiler WG-compiler-errors

Самый полезный комментарий

Текущий выход:

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required

Некоторые варианты:

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required
   = note: generic parameter `U` needs to be specified for foo::<T, U>()
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |                  |
   |                  you can specify the generic parameter here using `foo::<_, U>()`
   |
   = note: generic parameter `U` needs to be specified for `fn foo::<T, U>() -> T`
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U` in `fn foo<T, U>() -> T`
   |                  |
   |                  specify `U` using `foo::<_, U>()`
   |

Все 3 Комментарий

Привет @nikomatsakis

Я буду работать над этим.

Еще раз спасибо!

Текущий выход:

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required

Некоторые варианты:

error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |
   = note: type annotations or generic parameter binding required
   = note: generic parameter `U` needs to be specified for foo::<T, U>()
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U`
   |                  |
   |                  you can specify the generic parameter here using `foo::<_, U>()`
   |
   = note: generic parameter `U` needs to be specified for `fn foo::<T, U>() -> T`
error[E0282]: type annotations needed
  --> $DIR/xxx.rs:xx:xx
   |
14 |     let x: i32 = foo();
   |                  ^^^ cannot infer type for `U` in `fn foo<T, U>() -> T`
   |                  |
   |                  specify `U` using `foo::<_, U>()`
   |

Это примечание, в частности, заставляет мои глаза остекленеть:

   = note: type annotations or generic parameter binding required

Давайте обязательно удалим это. :)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги