简体   繁体   English

我如何借用一个可变的字符串来将自己推到自己身上?

[英]How do I borrow a String as mutable to push itself to itself?

I am trying to solve a problem from r/dailyprogrammer and have run into a problem with borrowing a String as mutable.我正在尝试解决来自r/dailyprogrammer的问题,并且遇到了将String借用为可变的问题。

I'm trying to see if a String has been "looped" around.我正在尝试查看String是否已“循环”。 Comparing "hello" to "llohe" would return true whereas "hello" to "oelhl" would not.比较“hello”和“llohe”会返回true,而“hello”和“oelhl”不会。 My strategy was to double one string and see if it contains the other one:我的策略是将一个字符串加倍,看看它是否包含另一个字符串:

fn main() {
    let x = String::from("hello");
    let mut y = String::from("llohe");
    println!("{}", compare(x, &mut y));
}

fn compare(x: String, y: &mut String) -> bool {
    y.push_str(y.as_str());
    if y.contains(&x) {
        true
    } else {
        false
    }
}
error[E0502]: cannot borrow `*y` as mutable because it is also borrowed as immutable
 --> src/main.rs:8:5
  |
8 |     y.push_str(y.as_str());
  |     ^^--------^-^^^^^^^^^^
  |     | |        |
  |     | |        immutable borrow occurs here
  |     | immutable borrow later used by call
  |     mutable borrow occurs here

I don't know where the heck I'm doing that.我不知道我到底在做什么。 I am trying to become friends with the compiler, but it is quite prickly.我试图与编译器成为朋友,但这很棘手。

It is not possible to borrow a String as mutable to push itself to itself.不可能借用一个可变的String来将自身推向自身。 Instead, you have to first clone the string, and then push the cloned version to itself:相反,您必须首先克隆字符串,然后将克隆的版本推送到自身:

y.push_str(y.clone().as_str());

However, in your case you do not need to pass a mutable reference to y , because you are not modifying it.但是,在您的情况下,您不需要将可变引用传递给y ,因为您没有修改它。 Instead, you can create a new string with String::repeat() :相反,您可以使用String::repeat()创建一个新字符串:

fn main() {
    let x = String::from("hello");
    let y = String::from("llohe");
    println!("{}", compare(x, y));
}

fn compare(x: String, y: String) -> bool {
    y.repeat(2).contains(&x)
}

As an answer to the problem instead of the question, you don't need heap allocation at all;作为问题的答案而不是问题,您根本不需要堆分配; iterators provide enough capability here:迭代器在这里提供了足够的能力:

fn main() {
    let x = "hello";
    let y = "llehe";
    println!("{}", compare(x, y));
}

fn compare(x: &str, y: &str) -> bool {
    let x = x.as_bytes();
    let mut y = y.as_bytes().iter().chain(y.as_bytes());

    loop {
        let yy = y.clone();
        if x.iter().eq(yy.take(x.len())) {
            return true; // or break true;
        }
        if y.next().is_none() {
            return false; // or break false;
        }
    }
}

There's no reason to have a mut ref at all, you can skip all that:根本没有理由使用mut ref,您可以跳过所有这些:

fn main() {
    let x = String::from("hello");
    let y = String::from("llohe");
    println!("{}", compare(&x, &y));
}

fn compare(x: &String, y: &String) -> bool {
    let mut z = y.clone();
    
    z.push_str(y.as_str());
    
    // You don't need to wrap a boolean in an if and return booleans,
    // just let the result of the test be the return value
    z.contains(x)
}

The as_str() function needs a reference to the string, but as you're holding a mutable reference that violates the borrow checker rules. as_str()函数需要对字符串的引用,但因为您持有一个违反借用检查器规则的可变引用。 Rust just isn't comfortable with all those references co-existing. Rust 只是不适应所有这些引用共存。

This is likely because you're asking to append to a string a copy of the string you're in the process of appending to, which could lead to problems.这可能是因为您要求将正在附加的字符串的副本附加到字符串,这可能会导致问题。 as_str needs the string to be stable, push_str needs to be able to change the string. as_str需要字符串稳定, push_str需要能够更改字符串。 They can't inter-operate like that.他们不能那样互操作。

You can side-step this by cloning the string:您可以通过克隆字符串来回避此问题:

fn main() {
    let x = String::from("hello");
    let mut y = String::from("llohe");
    println!("{}", compare(x, &mut y));
}

fn compare(x: String, y: &mut String) -> bool {
    y.push_str(y.clone().as_str());
    if y.contains(&x) {
        true
    } else {
        false
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM