通过索引访问借来的字符串中的字符

时间:2015-04-10 02:42:11

标签: rust

您如何通过索引访问借来的字符串中的元素?

直截了当的Python:

my_string_lst = list(my_string) 
print my_string_list[0]
print my_string[0]                # same as above

Rust(尝试1):

let my_string_vec = vec![my_string];    # doesn't work
println!("{}", my_string_vec[0]);       # returns entire of `my_string` 

Rust(尝试2):

let my_string_vec = my_string.as_bytes();  # returns a &[u8]
println!("{}", my_string_vec[0]);          # prints nothing

我的最终目标是坚持这样的循环:

for pos in 0..my_string_vec.len() {
    while shift <= pos && my_string_vec[pos] != my_string_vec[pos-shift] {
        shift += shifts[pos-shift];
    }
    shifts[pos+1] = shift;
}

for ch in my_string_vec {
    let pos = 0;    // simulate some runtime index
    if my_other_string_vec[pos] != ch {
        ...
    }
}

我认为在我的条件声明中可以使用my_string_vec.as_bytes()[pos]my_string_vec.as_bytes()[pos-shift],但我觉得这有一个糟糕的代码味道。

1 个答案:

答案 0 :(得分:1)

您可以使用char_at(index)来访问特定字符。如果要迭代字符串中的字符,可以使用chars()方法生成字符串中字符的迭代器。

具体无法使用索引语法的原因是,IIRC,因为索引语法会让人觉得它就像访问典型的C字符串式字符串中的字符一样,访问给定索引处的字符是一个恒定时间操作(即只访问数组中的单个字节)。另一方面,Rust中的字符串是Unicode,单个字符可能不一定只包含一个字节,使特定字符访问线性时间操作,因此决定使性能差异明确且清晰。

据我所知,没有可用于交换字符串中字符的方法(参见this question)。请注意,无论如何都不可能通过不可改变的借用字符串,因为这样的字符串不能修改。如果您严格交换,则必须使用String,或者&mut str,但我不太熟悉Unicode的错综复杂。

我建议您按照自己想要的方式构建String,这样您就不必担心借用字符串的可变性。您可以引用/查看借用的字符串,并根据您的逻辑相应地写入输出/构建字符串。

所以这个:

for pos in 0..my_string_vec.len() {
    while shift <= pos && my_string_vec[pos] != my_string_vec[pos-shift] {
        shift += shifts[pos-shift];
    }
    shifts[pos+1] = shift;
}

可能会变成这样的东西(未经过测试;不清楚你的逻辑是什么):

for ch in my_string.chars()
    while shift <= pos && ch != my_string.char_at(pos - shift) {
        // assuming shifts is a vec; not clear in question
        shift += shifts[pos - shift];
    }

    shifts.push(shift);
}

你的最后一个循环:

for ch in my_string_vec {
    let pos = 0;    // simulate some runtime index
    if my_other_string_vec[pos] != ch {
        ...
    }
}

那种似乎想要将字符串A中的给定字符与字符串B的相应字符(在相同位置)进行比较。为此,我建议使用第二个字符串来压缩第一个字符的字符迭代器,类似于:

for (left, right) in my_string.chars().zip(my_other_string.chars()) {
  if left != right {
  }
}

请注意,只要迭代器停止,zip()就会停止迭代,这意味着如果字符串的长度不同,那么它只会到达最短的字符串。

如果您需要访问&#34;字符索引&#34;信息,您可以将.enumerate()添加到该信息中,因此上述内容将更改为:

for (index, (left, right)) in my_string.chars().zip(my_other_string.chars()).enumerate()