我的代码中有一个函数,它接受&[&'a str]:

fn user_quicksort<'a>(list: &[&'a str]) -> Vec<&'a str>

在调用方中,我有一个Box<[Box<str>]>变量,我希望将其传递给它;但是,Rust给了我以下错误:

error[E0308]: mismatched types
  --> src\main.rs:36:33
   |
36 |     let sorted = user_quicksort(&input);
   |                  -------------- ^^^^^^ expected `&[&str]`, found `&Box<[Box<str>]>`
   |                  |
   |                  arguments to this function are incorrect
   |
   = note: expected reference `&[&str]`
              found reference `&Box<[Box<str>]>`

我使用Box<str>而不是String的原因是因为Box<str>是不可变的、更快的、更小的.

我该怎么办?

这就是我得到input分的原因:

let input = fs::read_to_string("input.txt")
    .expect("Unable to read file")
    .split("\n")
    .map(|s| s.to_string().into_boxed_str())
    .collect::<Box<[Box<str>]>>();

推荐答案

我不会在排序函数中强加序列的重复,而是让它对序列inplace进行排序.

这样,在调用点,我们可以 Select 是要更改原始序列,还是要保持它不排序并构建要排序的浅层副本.

克隆这个序列的成本会很高,因为每Box<str>个序列都会被克隆. 那么我们的排序函数应该能够对原始序列的Box<str>的序列和对浅拷贝的&str的序列起作用. 在参数中使用impl AsRef<str>会有所帮助,因为Box<str>&str(显然)都可以被认为是对str的引用.

fn user_quicksort(list: &mut [impl AsRef<str>]) {
    // rely on standard slice::sort_by() here
    list.sort_by(|a, b| a.as_ref().cmp(b.as_ref()));
}

fn main() {
    let mut input = std::fs::read_to_string("input.txt")
        .expect("Unable to read file")
        .split("\n")
        .map(|s| s.to_string().into_boxed_str())
        .collect::<Box<[Box<str>]>>();
    // if we want to keep the initial sequence as is,
    // then we create a shallow clone of the sequence and sort it
    let mut shallow_clone =
        input.iter().map(|s| s.as_ref()).collect::<Box<[&str]>>();
    for (s1, s2) in input.iter().zip(shallow_clone.iter()) {
        // just a check to be sure we didn't copy de str themselves
        if s1.as_ptr() != s2.as_ptr() {
            println!("!!! deep copy {:?} {:?}", s1, s2);
        }
    }
    user_quicksort(shallow_clone.as_mut());
    println!("sorted clone: {:?}", shallow_clone);
    println!("initial input: {:?}", input);
    // but if we want to sort the initial sequence,
    // no new allocation is needed
    user_quicksort(input.as_mut());
    println!("sorted input: {:?}", input);
}
/*
sorted clone: ["", "line 1", "line 2", "line 3", "line 4", "line 5"]
initial input: ["line 4", "line 1", "line 5", "line 2", "line 3", ""]
sorted input: ["", "line 1", "line 2", "line 3", "line 4", "line 5"]
*/

Rust相关问答推荐

为什么在Rust struct 中只允许最后一个字段具有动态大小的类型

为什么迭代器上的`. map(...)`的返回类型如此复杂?

泛型属性比较

从Rust调用C++虚拟方法即使在成功执行之后也会引发Access违规错误

如何正确地将App handler传递给Tauri中的其他模块?

如何循环遍历0..V.len()-1何时v可能为空?

告诉Rust编译器返回值不包含构造函数中提供的引用

铁 rust ,我的模块介绍突然遇到了一个问题

更合理的方法来设计样条线函数器?

无法将 rust 蚀向量附加到另一个向量

需要一个有序向量来进行 struct 初始化

在 Rust 中查找向量中 dyn struct 的索引

Rust 1.70 中未找到 Trait 实现

将引用移动到线程中

Rust并发读写引起的死锁问题

我如何取消转义,在 Rust 中多次转义的字符串?

是否可以通过可变引用推进可变切片?

Rust 函数指针似乎被borrow 判断器视为有状态的

Iterator::collect如何进行转换?

如何将 while 循环内的用户输入添加到 Rust 中的向量?