如何传递修改后的字符串参数? [英] How do I pass modified string parameters?

查看:51
本文介绍了如何传递修改后的字符串参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Rust 编程语言 的第 12 章,其中实现了不区分大小写的行搜索.对我来说两次实现相同的逻辑没有意义,所以我想如果我只是调用区分大小写的搜索函数并将参数转换为小写,那可能会奏效.它没有.

I'm on chapter 12 of The Rust Programming Language, where a case insensitive line search is implemented. It doesn't make sense to me to implement the same logic twice, so I figured if I just called the case sensitive search function with the parameters converted to lower case, that might work. It did not.

这是我的非工作代码:

fn main() {
    let a = search("Waldo", "where in\nthe world\nis Waldo?");
    let b = search("waldo", "where in\nthe world\nis Waldo?");
    let c = search_case_insensitive("waldo", "where in\nthe world\nis Waldo?");

    println!("{:?}", a);
    println!("{:?}", b);
    println!("{:?}", c);
}

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query) {
            results.push(line);
        }
    }

    results
}

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let query = query.to_lowercase();
    let contents2: &str = &contents.to_lowercase();

    search(&query, contents2)
}

我提出的大多数版本中的错误不可避免地非常类似于:

The error in most versions I've come up with is inevitably something very much like:

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:25:28
   |
25 |     let contents2: &str = &contents.to_lowercase();
   |                            ^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
...
28 | }
   | - temporary value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 23:1...
  --> src/main.rs:23:1
   |
23 | pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

推荐答案

EDIT 2:

既然你已经用 MCVE 更新了问题,并且你已经声明你不关心偏离书中的例子......这里是另一个版本,它通过使用 String<依赖于额外的分配/代码>:

EDIT 2:

Since you've updated the question with an MCVE and you've stated you don't care about straying away from the book examples... here is another version relying on extra allocations via the use of String:

fn main() {
    let a = search("Waldo", "where in\nthe world\nis Waldo?");
    let b = search("waldo", "where in\nthe world\nis Waldo?");
    let c = search_case_insensitive("waldo", "where in\nthe world\nis Waldo?");

    println!("{:?}", a);
    println!("{:?}", b);
    println!("{:?}", c);
}

pub fn search<S>(query: S, contents: S) -> Vec<String> where S: Into<String> {
    let query = query.into();
    let mut results = Vec::new();

    for line in contents.into().lines() {
        if line.contains(&query) {
            results.push(line.into());
        }
    }

    results

}

pub fn search_case_insensitive<S>(query: S, contents: S) -> Vec<String> where S: Into<String> {
    let query = query.into().to_lowercase();
    let contents = contents.into().to_lowercase();

    search(query, contents)
}

这里是 在游乐场

我意识到我从来没有真正给过你选择.以下是我可能会做的:

I realised I never really gave you an alternative. Here's what I would probably do:

pub enum SearchOptions {
    CaseSensitive,
    CaseInsensitive
}

pub fn search<'a>(query: &str, contents: &'a str, options: SearchOptions) -> Vec<&'a str> {
    let mut results = Vec::new();

    for line in contents.lines() {
        let check = match options {
            SearchOptions::CaseSensitive => line.contains(query),   
            SearchOptions::CaseInsensitive => line.to_lowercase().contains(&query.to_lowercase()),   
        };
    
        if check {
            results.push(line);
        }
    }

    results
}

这就是您可以去重复"的范围.

This is about as far as you could get "de-dupe"'ing it.

实际的问题是,当 contents 绑定到生命周期 'a 时,您正试图传递它……但是您真正想要的是";不区分大小写是 query.

The actual problem is that you're trying to pass the contents around when its bound to the lifetime 'a ... but what you really want to be "case insensitive" is the query.

这与生命周期 'a 并没有以完全相同的方式绑定,因此......工作:

This isn't bound to the lifetime 'a in quite the same way and as such ... works:

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let query = query.to_lowercase();
    search(&query, contents)
}

在这里

您仍然需要复制逻辑...因为您需要将小写查询与小写行匹配...这在本书的示例中进行了演示:

You'll need to still duplicate the logic though ... because you need to match the lowercase query with the lowercase line ... which is demonstrated in the examples in the book:

if line.to_lowercase().contains(&query) {
//      ^^^^^^^^^^^^^^ each LINE is converted to lowercase here in the insensitive search
    results.push(line);
}

如何停止重复逻辑?"- 好吧,它们一开始就不完全相同.我认为您的尝试并不完全是您所追求的(尽管很高兴得到纠正).

"How do I stop duplicating the logic?" - well they're not quite the same in the first place. I think your attempt wasn't quite what you were after in the first place (happy to be corrected though).

这篇关于如何传递修改后的字符串参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆