Подпись функции для общих номеров - PullRequest
0 голосов
/ 06 ноября 2018

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

Возможно, я атакую ​​проблему с неправильной точки зрения, но вот где я дошел до сих пор самостоятельно. Я не склонен делать эту работу таким образом; поэтому, если я пытаюсь решить проблему (создать небольшую библиотеку полезных математических функций) под неправильным углом зрения, то обязательно научите меня.

Допустим, я хочу функцию add, которая складывает два числа:

use std::ops::Add;

fn add(a: Add, b: Add) -> Add::Output {
    a + b
}

Это не скомпилируется. Вот детская площадка: https://play.integer32.com/?version=stable&mode=debug&edition=2015&gist=4589325b5c8d1f1b19440424878caa98

По сути, я получаю две ошибки. Первый:

error[E0393]: the type parameter `RHS` must be explicitly specified
 --> src/main.rs:8:11
  |
8 | fn add(a: Add, b: Add) -> Add::Output {
  |           ^^^ missing reference to `RHS`
  |
  = note: because of the default `Self` reference, type parameters must be specified on object types

Я прочитал главу о продвинутых чертах в книге Rust, так что я "вроде как" понимаю сообщение RHS, но они решают проблему добавления Add черта вашей конкретной структуры данных (a Point в примере); но никогда не показывайте сигнатуру функции, которая принимает все, что может быть добавлено. Так что я немного растерялся.

Вторая ошибка:

error[E0223]: ambiguous associated type
 --> src/main.rs:8:27
  |
8 | fn add(a: Add, b: Add) -> Add::Output {
  |                           ^^^^^^^^^^^ ambiguous associated type
  |
  = note: specify the type using the syntax `<Type as std::ops::Add>::Output`

Это исчезнет, ​​если я напишу <i32 as Add>::Output, но это не то, что я хочу. Я специально хочу, чтобы эта функция работала со всем, что можно добавить (при условии, что a и b имеют одинаковый тип).

1 Ответ

0 голосов
/ 06 ноября 2018

Вы объединяете черты и типы .

Add - это черта . Черта может быть реализована для типа или класса типов, но это не сам тип.

Аргументы функции должны быть объявлены с типом , а не признаком. Это основная проблема с вашим прототипом - Add не является типом, поэтому вы не можете использовать его как тип переменной или аргумента функции.

Rust позволяет объявлять универсальные типы , по сути, переменные типа. Затем вы можете поместить границы признаков в универсальные типы, что требует, чтобы какой-либо тип, заменяющий универсальный тип, реализовывал некоторую черту. Ваш пример использования параметра общего типа T выглядит следующим образом:

fn add<T: Add>(a: T, b: T) -> T::Output

Для этого прототипа требуется, чтобы a и b имели одинаковый тип T, а T реализовал черту Add.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...