Понимание проблем типа приписывания - PullRequest
1 голос
/ 01 мая 2020

Извините, но я так растерялся, что не знаю, как сформулировать вопрос. Если у вас есть предложение для лучшего названия, пожалуйста, дайте мне знать.

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

Я определил следующую черту и функцию , Исходя из моего ограниченного понимания, я определяю тип как u16:

//  src/range.rs

pub struct Range {
    pub min: u16,
    pub max: u16,
    pub current: u16
}

impl Range {
    pub fn new(min: u16, max: u16, current: u16) -> Self {
        Range{ min, max, current }
    }

Далее я хотел проверить new() внутри своих интеграционных тестов:

//  tests/integration_tests.rs

use confine::range::Range;

#[test]
fn new_confine() {
    assert_eq!(Range{min: 1, max: 6, cursor: 1}, Range::new(min: 1, max: 6, cursor: 1));

Почему компилятор смущен типом, когда я определил структуру для u16? Я тоже пытался явно написать 1u16.

Я получаю следующую ошибку:

error: expected type, found `1`
 --> tests/integration_test.rs:5:70
  |
5 |     assert_eq!(Confine{min: 1, max: 6, cursor: 1}, Confine::new(min: 1, max: 6, cursor: 1));
  |                                                                    - ^ expected type
  |                                                                    |
  |                                                                    tried to parse a type due to this type ascription
  |

1 Ответ

1 голос
/ 01 мая 2020

Это основное различие между инициализацией структуры и вызовом функции в Rust. При инициализации структуры поля именуются (при условии, что структура имеет именованные поля), но именованные аргументы в настоящее время не поддерживаются для функций.

Чтобы вызвать Confine::new, просто пропустите min:, max: и cursor:.

assert_eq!(
    Range {min: 1, max: 6, cursor: 1},
    Range::new(1, 6, 1)
);

Теперь объясним ошибку. Аргументами функции являются разделенные запятыми списки выражений, поэтому (например) min: 1 анализируется как выражение. Это идет хорошо до :. Выражение, содержащее : (по крайней мере, в этой позиции), должно иметь тип ascription (которое нестабильно, но все же реализовано в грамматике). Это означает, что остальная часть min: 1 должна быть типом, поэтому 1 анализируется как тип. Это явно идет не так, поскольку 1 является целым числом, а не типом.

Ничто из этого не имеет никакого отношения к фактическим типам аргументов. Просто иметь (1, 6, 1), как указано выше, будет достаточно, чтобы сделать вывод, что они u16.


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

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