Ржавчина, использующая методы итераторов в env::Args, выдает ошибки, может быть, ошибку?

#rust #iterator

Вопрос:

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

То, что я пытаюсь сделать,-это проанализировать аргументы командной строки с помощью итераторов. Код проекта:

     pub fn new(mut args: env::Args) -> Result<Config, amp;'static str> {
        args.next();
        
        let query = match args.next() {
            Some(arg) => arg,
            None => return Err("No query string"),
        };
        
        let filename = match args.next() {
            Some(arg) => arg,
            None => return Err("No Filename"),
        };
        // --snip--
    }
 

Мне нужно сравнить первый итератор с необязательным аргументом командной строки «-c», не используя итератор в случае, если аргумента там нет.

Первое, что я попробовал, было args.eq([String::from("-c")].iter());

Но получил ошибку no implementation for `String == amp;String

Далее я попытался использовать args.copied().collect(); получил ошибку expected struct `String`, found reference ошибки?

Потом я попробовал args.map(|x: amp;String| x).collect(); и получил expected signature of `fn(String) -> _` ошибку?

Я пробовал и другие методы, такие как: by_ref, peekable, and cloned

Мой вопрос таков:

Как я могу сравнить первый элемент итератора env::Args со строкой, не используя итератор?

Ответ №1:

Как я могу сравнить первый элемент итератора an env::Args со строкой, не используя итератор?

Вы, вероятно , захотите использовать Iterator::peekable , который преобразует ваш исходный итератор в итератор, предлагающий метод peek . Этот метод возвращает ссылку на следующий элемент без продвижения (или использования) итератора!

 let mut it = args.peekable();
if it.peek().map(|s| s.as_str()) == Some("-a") {
    
}
 

С тех пор it.peek() Option<amp;String> я также сопоставил его s.as_str() , чтобы иметь возможность легко сравнивать Some("-a") , не выделяя String для "-a" .

Комментарии:

1. Это не сработало. Я получаю ошибку «перемещение происходит из args -за того , что имеет тип Args , который не реализует Copy признак»

2. @vis. 15 Вы должны использовать it впоследствии, args действительно перемещены it .

3. Почему не .cloned() работает дальше env::Args ?

4. Потому что смысл cloned() в том , чтобы преобразовать an amp;T в a T , но Args является итератором String s, так что уже a T . Клонирование просто дублировало бы содержимое без всякой причины.