В операторе [(vec[0],vec[1],vec[2])].iter()
вы создаете массив (фиксированной длины) с одним элементом, а затем сразу итерируете его.Единственный используемый вами метод итератора - map
, поэтому, вероятно, было бы гораздо более идиоматичным просто иметь
let year = vec[0];
let month = vec[1];
let day = vec[2];
, а затем продолжить без использования map
.Еще лучше, вы можете использовать это как возможность для анализа day
как целое число, вместо того, чтобы анализировать каждую ветвь операторов сравнения.Это также устранит проблему, связанную с тем, что тип, который анализирует day
, не может быть выведен.Вам придется писать day.parse::<i32>()
каждый раз, когда вы его анализируете, так что гораздо проще просто сделать это один раз наверху.Вы также можете проанализировать year
, так как вам все равно понадобится сделать это ниже.После этих изменений вы не захотите снова анализировать day
и year
, поэтому удалите все операторы .parse().unwrap()
.
let year: i32 = vec[0].parse().unwrap();
let month = vec[1];
let day: i32 = vec[2].parse().unwrap();
После этого изменения, предложенные компилятором, должны бытьдостаточно, чтобы заставить это работать.Вам больше не нужно сопоставлять month
как &&str
(например, &"01"
), поскольку вы не создаете массив &str
и не перебираете ссылки на него (в вашем исходном коде было бы лучшеиспользуйте into_iter()
вместо iter()
, чтобы избежать этого).Кроме того, компилятор скажет вам, что совпадение на month
не является исчерпывающим.Вам нужно будет добавить ответвительную ветвь, если входные данные не соответствуют ни одной из других ветвей.Я бы предложил что-то вроде _ => panic!("Invalid month")
в конце операторов матча.
Просто несколько дополнительных советов, чтобы ваш код выглядел намного лучше.Команда cargo fmt
(этот инструмент также существует в разделе «ИНСТРУМЕНТЫ» на игровой площадке) автоматически отформатирует ваш код в более идиоматическом стиле.Это просто облегчает чтение в целом.Я бы также порекомендовал запустить cargo clippy
(также доступен на игровой площадке), чтобы отследить любые возможные ошибки и сделать ваш код еще более идиоматичным.В этом случае clippy делает несколько небольших предложений.
Просто общий совет по кодированию, я бы также разделил эту функцию на функцию, которая анализирует дату, и функцию, которая находит номер дня в году.,Таким образом, вам не нужно делать и то и другое одновременно, и об этом легче думать.(Это не совсем соответствует формату, который вам дает задание, поэтому вам придется вызывать эту функцию синтаксического анализа из day_of_year
функции.)
Я понимаю, что задание просит вас вернуться i32
, но так как это вычисление может быть неудачным, было бы гораздо лучше вернуть Option<i32>
(или еще лучше Result<i32, Error>
, где Error
- это некоторое описание возможных путей, которые могут пойти не так),Это будет работать лучше всего, если вы также последуете предложению выше, чтобы разделить его на две функции.Затем вы можете проанализировать и проверить дату в первой функции, а затем с учетом правильной даты вычислить день года.Это позволит вам удалить все вызовы unwrap
(и явную панику, которую я предложил).Зная, что ваша функция не паникует, это приятное чувство.
Наконец, в этом коде много повторений, так что вы можете быть в состоянии вычленить вещи и не повторять себя так много.Например, вместо двух операторов сопоставления в зависимости от того, является ли это високосным годом или нет, просто укажите одно совпадение и добавьте одно, если это високосный год.Вы также можете указать количество дней в каждом месяце в массиве, например [31, 28, 31, 30, ...]
.Затем вы можете просто использовать номер месяца и сложить соответствующее количество дней.
(также очень маленький спор: проблема указывает на то, что он использует григорианский календарь, который не имеет особых случаев для прыжкалет, кратных 3200 или 172 800)