Что такое однострочное решение для получения всего, кроме последнего элемента в срезе, без использования индекса последнего элемента? - PullRequest
0 голосов
/ 29 апреля 2020

В Python я могу сделать:

a = [1,2,3]
b = a[:-1] #1,2

Rust имеет синтаксис для получения фрагмента массива диапазон , где вы предоставляете последний индекс, не включительно:

let a = vec![1, 2, 3];
let b = &a[0..2]; // [1, 2]

Если я использую -1, это вызывает ошибку компилятора:

let a = vec![1, 2, 3];
let b = &a[0..-1];
error[E0277]: the trait bound `usize: std::ops::Neg` is not satisfied
 --> src/lib.rs:3:19
  |
3 |     let b = &a[0..-1];
  |                   ^^ the trait `std::ops::Neg` is not implemented for `usize`

Как я могу это сделать?

пример:

я хочу преобразовать "x1 :: x2 :: x3 :: ... :: xn" в "x1 :: x2 :: x3 :: ... xn-1"
в python одна линия твердения должна быть

case_1 = "a::b::c";
ret = case1.split("::")[:-1]

, но каково это решение одной линии для ржавчины

let case_1 =  "a::b::c";
let ret = case_1.split("::").collect::<Vec<_>>() //what could i do next?

Ответы [ 3 ]

6 голосов
/ 29 апреля 2020

Я думаю, split_last - это то, что вы ищете: он возвращает необязательный 2-кортеж, содержащий ссылку на последний элемент и фрагмент до (но исключая) последнего элемента.

Т.е. a.split_last().unwrap().1 получает то, что вы запрашиваете (unwrap предполагает, что a не пусто).

Если вы хотите изменить значения, есть также его двоюродный брат split_last_mut.

1 голос
/ 29 апреля 2020

Вы можете использовать -1 до тех пор, пока вы добавляете vec.len() заранее:

fn main() {
    let a = vec![1, 2, 3];
    println!("{:?}", &a[0..a.len() - 1]);
}

Поскольку OP запросил однострочник, вы можете удалить символ новой строки и использовать не-идиоматизм c Форматирование ржавчины:

fn main() {
    let a = vec![1, 2, 3]; println!("{:?}", &a[0..a.len() - 1]);
}
0 голосов
/ 29 апреля 2020

Вероятно, не то, что вы хотите, так как вы, кажется, ищете менее подробное решение, но вы можете использовать pop; с векторами, он мутирует исходный вектор.

let a = vec![1, 2, 3];
let mut init = a.clone();
&init.pop();
assert_eq!(init, &[1, 2]);
...