Skip to content

Struct std::io::IoSliceMut

rust
#[repr(transparent)]
pub struct IoSliceMut<'a>(_);

Read::read_vectored 使用的缓冲区类型。

它在语义上是 &mut [u8] 的包装器,但保证与 Unix 平台上的 iovec 类型和 Windows 上的 WSABUF 类型的 ABI 兼容。

Implementations

impl<'a> IoSliceMut<'a>

new

创建一个新的 IoSliceMut,包装一个字节切片。

rust
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a>

参数

  • buf:一个字节切片

返回值:返回一个新的 IoSliceMut

rust
use std::io::IoSliceMut;

fn main() {
    let mut buf =vec![1,2,3];
    let s = IoSliceMut::new(&mut buf);
    println!("{:?}", s);  // [1,2,3]
}

Panic

如果切片大于 4GB,则在 Windows 上使用 panics。

advance

nightly-only

前进切片的内部游标。

另请参见 IoSliceMut::advance_slices 以推进多个缓冲区的游标。

rust
pub fn advance(&mut self, n: usize)

参数

  • n:需要前进的步数
rust
use std::io::IoSlice;

fn main() {
    let buf =vec![1,2,3];
    let mut s = IoSliceMut::new(&buf);
    s.advance(2);
    println!("{:?}", s);  // [3]
}

Panic

试图超越切片末端时出现 panic。

advance_slices

前进多个切片中的内部游标。

rust
pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize)

参数

  • bufs:一个二维数组切片
  • n:需要前进的步数

返回值

rust
use std::io::IoSlice;

fn main() {

    let buf1 = [1,2,3];
    let buf2 = [4,5,6];
    let buf3 = [7,8,9];
    let mut bufs = &mut [
        IoSliceMut::new(&buf1),
        IoSliceMut::new(&buf2),
        IoSliceMut::new(&buf3),
    ][..];

    // 将 10 个字节标记为已写入。
    IoSliceMut::advance_slices(&mut bufs, 5);
    println!("{:?}", bufs);   // [[6], [7, 8, 9]]
}

Panic

试图超越切片末端时出现 panic。

Methods from Deref<Target = [u8]>

flatten

将一个二维的数组切片,转化为一维的数组切片

&[[T; N]],并将其展平为 &[T]

rust
pub fn flatten(&self) -> &[T]

返回值:返回被扁平化的新数组

rust
#![feature(slice_flatten)]

assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);

assert_eq!(
    [[1, 2, 3], [4, 5, 6]].flatten(),
    [[1, 2], [3, 4], [5, 6]].flatten(),
);

let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
assert!(slice_of_empty_arrays.flatten().is_empty());

let empty_slice_of_arrays: &[[u32; 10]] = &[];
assert!(empty_slice_of_arrays.flatten().is_empty());

flatten_mut

&mut [[T; N]],并将其展平为 &mut [T]

rust
pub fn flatten_mut(&mut self) -> &mut [T]

返回值:返回被扁平化的新数组的可变引用

rust
#![feature(slice_flatten)]

fn add_5_to_all(slice: &mut [i32]) {
    for i in slice {
        *i += 5;
    }
}

let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
add_5_to_all(array.flatten_mut());
assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);

panic

如果结果切片的长度会溢出 usize,则会出现 panic。

这仅在展平零大小类型的数组切片时才有可能,因此在实践中往往无关紧要。 如果是 size_of::<T>() > 0,这将永远不会 panic。

len

获取切片中的元素数

rust
pub fn len(&self) -> usize

返回值:返回切片中的元素数

rust
let a = [1, 2, 3];
assert_eq!(a.len(), 3);

is_empty

判断切片是否为空

rust
pub fn is_empty(&self) -> bool

返回值:如果切片的长度为,则返回 true.

rust
let a = [1, 2, 3];
assert!(!a.is_empty());

first

返回切片的第一个元素; 如果为空,则返回 None

rust
pub fn first(&self) -> Option<&T>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含第一个元素
  • 若切片为空,则返回None
rust
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());

let w: &[i32] = &[];
assert_eq!(None, w.first());

first_mut

返回指向切片第一个元素的可变指针,如果为空则返回 None

rust
pub fn first_mut(&mut self) -> Option<&mut T>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含第一个元素的可变指针
  • 若切片为空,则返回None
rust
let x = &mut [0, 1, 2];

if let Some(first) = x.first_mut() {
    *first = 5;
}
assert_eq!(x, &[5, 1, 2]);

split_first

把切片中的第一个元素和剩余其他元素分开

返回切片的第一个元素和所有其他元素,如果为空,则返回 None

rust
pub fn split_first(&self) -> Option<(&T, &[T])>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含一个元组,第一个元素是切片的第一个元素,第二个元素是切片中的剩余元素
  • 若切片为空,则返回None
rust
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first() {
    assert_eq!(first, &0);
    assert_eq!(elements, &[1, 2]);
}

split_first_mut

把切片中的第一个元素和剩余其他元素分开

返回切片的第一个元素的可变指针和所有其他元素,如果为空,则返回 None

rust
pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含一个元组,第一个元素是切片的第一个元素的可变指针,第二个元素是切片中的剩余元素
  • 若切片为空,则返回None
rust
let x = &mut [0, 1, 2];

if let Some((first, elements)) = x.split_first_mut() {
    *first = 3;
    elements[0] = 4;
    elements[1] = 5;
}
assert_eq!(x, &[3, 4, 5]);

split_last

把切片中的最后一个一个元素和剩余其他元素分开

返回切片的最后一个元素和所有其他元素组成的数组切片,如果为空,则返回 None

rust
pub fn split_last(&self) -> Option<(&T, &[T])>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含一个元组,第一个元素是切片的最后一个元素,第二个元素是切片中的剩余元素
  • 若切片为空,则返回None
rust
let x = &[0, 1, 2];

if let Some((last, elements)) = x.split_last() {
    assert_eq!(last, &2);
    assert_eq!(elements, &[0, 1]);
}

split_last_mut

把切片中的最后一个一个元素和剩余其他元素分开

返回切片的最后一个元素的可变指针和所有其他元素组成的数组切片,如果为空,则返回 None

rust
pub fn split_last(&self) -> Option<(&T, &[T])>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含一个元组,第一个元素是切片的最后一个元素,第二个元素是切片中的剩余元素组成的数组切片
  • 若切片为空,则返回None
rust
let x = &mut [0, 1, 2];

if let Some((last, elements)) = x.split_last_mut() {
    *last = 3;
    elements[0] = 4;
    elements[1] = 5;
}
assert_eq!(x, &[4, 5, 3]);

last

获取切片的最后一个元素

返回切片的最后一个元素; 如果为空,则返回 None

rust
pub fn last(&self) -> Option<&T>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含最后一个元素
  • 若切片为空,则返回None
rust
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());

let w: &[i32] = &[];
assert_eq!(None, w.last());

last_mut

获取切片的最后一个元素

返回切片的最后一个元素的可变指针; 如果为空,则返回 None

rust
pub fn last_mut(&mut self) -> Option<&mut T>

返回值:返回一个Option

  • 若切片不为空,则在Some中包含最后一个元素的可变指针
  • 若切片为空,则返回None
rust
let x = &mut [0, 1, 2];

if let Some(last) = x.last_mut() {
    *last = 10;
}
assert_eq!(x, &[0, 1, 10]);

first_chunk

nightly-only

获取切片的前N个元素

rust
pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

参数

  • N:一个长度

返回值:返回一个Option

  • 若N没有超过切片长度,则在Some中包含前N个元素
  • 若N超过切片长度,则返回None
rust
fn main() {
	let arr=[1,2,3,4,5,6,7,8,9];
	println!("{:?}", arr.first_chunk::<5>());   // Some([1, 2, 3, 4, 5])

	let arr=[1,2,3,4,5,6,7,8,9];
	println!("{:?}", arr.first_chunk::<100>());   // None
}

first_chunk_mut

nightly-only

返回切片的前 N 元素的可变引用,如果它的元素少于 N,则返回 None

rust
pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

泛型参数

  • N:N是一个数量,代表前N个元素

返回值:返回一个Option,若获取成功则Ok包含前N个元素的数组切片的可变引用

rust
#![feature(slice_first_last_chunk)]

let x = &mut [0, 1, 2];

if let Some(first) = x.first_chunk_mut::<2>() {
    first[0] = 5;
    first[1] = 4;
}
assert_eq!(x, &[5, 4, 2]);

split_first_chunk

nightly-only

获取切片的前N个元素和剩余元素

rust
pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

参数

  • N:一个长度

返回值:返回一个Option

  • 若N没有超过切片长度,则在Some中包含一个元素,第一个元素是切片的前N个元素,第二是元素是切片的剩余元素
  • 若N超过切片长度,则返回None
rust
#![feature(slice_first_last_chunk)]

let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first_chunk::<2>() {
    assert_eq!(first, &[0, 1]);
    assert_eq!(elements, &[2]);
}

split_first_chunk_mut

nightly-only

把切片从第N个元素处,切割为两个切片,并返回两个切片的可变引用

rust
pub fn split_first_chunk_mut<const N: usize>(
    &mut self
) -> Option<(&mut [T; N], &mut [T])>

泛型参数

  • N:代表切片的前N个元素

返回值:返回一个Option,OK内包含一个元组,如果元素少于 N,则返回 None

  • 元组第一个元素为切片前N个元组所组成的切片的可变引用
  • 第二个元素为剩下的元素所组成的切片
rust
fn main() {
    let x = &mut [0, 1, 2, 3, 4, 5];

    if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
        println!("{:#?}", first); // [0,1]
        println!("{:#?}", elements); // [2,3,4,5]
        
        // 可以被修改
        first[0] = 3;
        first[1] = 4;
        elements[0] = 5;
    }
}

split_last_cunk

获取切片的最后N个元素和剩余元素

rust
pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

参数

  • N:一个长度

返回值:返回一个Option

  • 若N没有超过切片长度,则在Some中包含一个元素,第一个元素是切片的前N个元素,第二是元素是切片的剩余元素
  • 若N超过切片长度,则返回None
rust
#![feature(slice_first_last_chunk)]

let x = &[0, 1, 2];

if let Some((last, elements)) = x.split_last_chunk::<2>() {
    assert_eq!(last, &[1, 2]);
    assert_eq!(elements, &[0]);
}

split_last_cunk_mut

nightly-only

把切片从倒数第N个元素处,切割为两个切片,并返回两个切片的可变引用

rust
pub fn split_last_chunk_mut<const N: usize>(
    &mut self
) -> Option<(&mut [T; N], &mut [T])>

泛型参数

  • N:代表切片的倒数第N个元素

返回值:返回一个Option,OK内包含一个元组,如果元素少于 N,则返回 None

  • 元组第一个元素为切片倒数前N个元组所组成的切片的可变引用
  • 第二个元素为剩下的元素所组成的切片
rust
#![feature(slice_first_last_chunk)]

let x = &mut [0, 1, 2];

if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
    last[0] = 3;
    last[1] = 4;
    elements[0] = 5;
}
assert_eq!(x, &[5, 3, 4]);

last_chunk

获取切片的最后N个元素

rust
pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

泛型参数

  • N:代表倒数前N个元素

返回值:返回一个Option

  • 若N没有超过切片长度,则在Some中包含最后N个元素
  • 若N超过切片长度,则返回None
rust
#![feature(slice_first_last_chunk)]

let u = [10, 40, 30];
assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());

let v: &[i32] = &[10];
assert_eq!(None, v.last_chunk::<2>());

let w: &[i32] = &[];
assert_eq!(Some(&[]), w.last_chunk::<0>());

last_chunk_mut

nightly-only

返回切片倒数前N个元素所组成的切片的可变引用

rust
pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

泛型参数

  • N:代表倒数前N个元素

返回值:返回一个Option,成功则包含倒数前N个元素所组成的切片的可变引用

rust
fn main() {
    let x = &mut [0, 1, 2];

    if let Some(last) = x.last_chunk_mut::<2>() {
        println!("{:#?}", last); // [1,2]
        last[0] = 10;
        last[1] = 20;
    }
    assert_eq!(x, &[0, 10, 20]);
}

get

根据索引的类型返回对元素或子切片的引用。

rust
pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where
    I: SliceIndex<[T]>,

参数

  • index:一个SliceIndex,需要获取的目标元素的索引

返回值

  • 如果给定位置,则返回该位置上的元素的引用,如果越界则返回 None
  • 如果给定范围,则返回对应于该范围的子切片; 如果越界,则返回 None
rust
let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));

get_mut

获取index处切片元素的可变引用

rust
pub fn get_mut<I>(
    &mut self,
    index: I
) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where
    I: SliceIndex<[T]>,

参数

  • index:一个SliceIndex,需要获取的目标元素的索引

返回值

  • 如果给定位置,则返回该位置上的元素的可变引用,如果越界则返回 None
  • 如果给定范围,则返回对应于该范围的子切片的可变引用; 如果越界,则返回 None
rust
let x = &mut [0, 1, 2];

if let Some(elem) = x.get_mut(1) {
    *elem = 42;
}
assert_eq!(x, &[0, 42, 2]);

get_unchecked

返回对元素或子切片的引用,而不进行边界检查

有关安全的选择,请参见 get

rust
pub unsafe fn get_unchecked<I>(
    &self,
    index: I
) -> &<I as SliceIndex<[T]>>::Output
where
    I: SliceIndex<[T]>,

参数

  • index:一个SliceIndex,需要获取的目标元素的索引

返回值:返回索引处的目标元素

rust
let x = &[1, 2, 4];

unsafe {
    assert_eq!(x.get_unchecked(1), &2);
}

Safety

即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior

get_unchecked_mut

不进行边界检查,获取元素或子切片的可变引用

rust
ub unsafe fn get_unchecked_mut<I>(
    &mut self,
    index: I
) -> &mut <I as SliceIndex<[T]>>::Output
where
    I: SliceIndex<[T]>,

参数

  • index:一个SliceIndex,需要获取的目标元素的索引

返回值

rust
let x = &mut [1, 2, 4];

unsafe {
    let elem = x.get_unchecked_mut(1);
    *elem = 13;
}
assert_eq!(x, &[1, 13, 4]);

as_ptr

将裸指针返回到切片的缓冲区。

调用者必须确保切片比该函数返回的指针有效,否则它将最终指向垃圾。

调用者还必须确保指针 (non-transitively) 所指向的内存 (从 UnsafeCell 内部除外) 永远不会使用此指针或从其派生的任何指针写入。 如果需要更改切片的内容,请使用 as_mut_ptr

修改此切片引用的容器可能会导致重新分配其缓冲区,这也将使指向它的任何指针无效。

rust
pub fn as_ptr(&self) -> *const T

返回值:返回裸指针

rust
let x = &[1, 2, 4];
let x_ptr = x.as_ptr();

unsafe {
    for i in 0..x.len() {
        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
    }
}

as_mut_ptr

返回指向切片缓冲区的不安全可变指针。

调用者必须确保切片比该函数返回的指针有效,否则它将最终指向垃圾。

修改此切片引用的容器可能会导致重新分配其缓冲区,这也将使指向它的任何指针无效。

rust
pub fn as_mut_ptr(&mut self) -> *mut T

返回值:返回指向切片缓冲区的不安全可变指针

rust
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr();

unsafe {
    for i in 0..x.len() {
        *x_ptr.add(i) += 2;
    }
}
assert_eq!(x, &[3, 4, 6]);

as_ptr_range

返回跨越切片的两个裸指针。

返回的范围是半开的,这意味着结束指针将 one 指向 切片的最后一个元素。 这样,一个空的切片由两个相等的指针表示,两个指针之间的差表示切片的大小。

有关使用这些指针的警告,请参见 as_ptr。结束指针需要格外小心,因为它没有指向切片中的有效元素。

此函数对于与外部接口进行交互很有用,该外部接口使用两个指针来引用内存中的一系列元素,这在 C++ 中很常见。

检查指向元素的指针是否引用了此切片的元素,这也可能很有用:

rust
pub fn as_ptr_range(&self) -> Range<*const T>

返回值:返回跨越切片的两个裸指针。

rust
let a = [1, 2, 3];
let x = &a[1] as *const _;
let y = &5 as *const _;

assert!(a.as_ptr_range().contains(&x));
assert!(!a.as_ptr_range().contains(&y));

as_mut_ptr_range

返回跨越切片的两个不安全的可变指针。

返回的范围是半开的,这意味着结束指针将 one 指向 切片的最后一个元素。 这样,一个空的切片由两个相等的指针表示,两个指针之间的差表示切片的大小。

有关使用这些指针的警告,请参见 as_mut_ptr。 结束指针需要格外小心,因为它没有指向切片中的有效元素。

此函数对于与外部接口进行交互很有用,该外部接口使用两个指针来引用内存中的一系列元素,这在 C++ 中很常见。

rust
pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

swap

在切片中交换两个元素。

rust
pub fn swap(&mut self, a: usize, b: usize)

参数

  • a:第一个元素的索引
  • b:第二个元素的索引
rust
let mut v = ["a", "b", "c", "d", "e"];
v.swap(2, 4);
assert!(v == ["a", "b", "e", "d", "c"]);

swap_unchecked

nightly-only

在不做边界检查的情况下交换切片中的两个元素。

有关安全的替代方案,请参见 swap

rust
pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

参数

  • a - 第一个元素的索引
  • b - 第二个元素的索引
rust
#![feature(slice_swap_unchecked)]

let mut v = ["a", "b", "c", "d"];
// SAFETY: 我们知道 1 和 3 都是切片的索引
unsafe { v.swap_unchecked(1, 3) };
assert!(v == ["a", "d", "c", "b"]);

TIP

使用越界索引调用此方法是未定义的行为。 调用者必须保证 a < self.len()b < self.len()

reverse

适当地反转切片中元素的顺序。

rust
pub fn reverse(&mut self)

示例

rust
let mut v = [1, 2, 3];
v.reverse();
assert!(v == [3, 2, 1]);

iter

返回切片上的迭代器。

迭代器从头到尾产生所有项。

rust
pub fn iter(&self) -> Iter<'_, T>

返回值:返回切片上的迭代器。

rust
let x = &[1, 2, 4];
let mut iterator = x.iter();

assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);

iter_mut

返回允许修改每个值的迭代器。

迭代器从头到尾产生所有项。

rust
pub fn iter_mut(&mut self) -> IterMut<'_, T>

返回值:返回一个IterMut,里面的迭代元素都可改变

rust
let x = &mut [1, 2, 4];
for elem in x.iter_mut() {
    *elem += 2;
}
assert_eq!(x, &[3, 4, 6]);

chunks

把一个切片分成指定长度的若干个切片,若剩余的元素小于指定长度,则最后一块的长度为剩余元素数

rust
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

参数

  • chunk_size:每一个块的大小

返回值:返回一个Chunks迭代器

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for chunk in v.chunks(2) {
        println!("{:?}", chunk);
    }

	/*
		[1, 2]
		[3, 4]
		[5]
	 */
}

panic

panic 会发生在如果 chunk_size 是 0.

chunks_mut

把一个切片分成若干个指定长度的切片的可变引用,若剩余的元素小于指定长度,则最后一块的长度为剩余元素数

rust
pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

参数

  • chunk_size:每一个块的大小

返回值:返回一个ChunksMut迭代器

rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    for chunk in v.chunks_mut(2) {
        chunk[0] += 1;
        println!("{:?}", chunk);
    }

	/*
	 	[2, 2]
		[4, 4]
		[6]
	 */
}

TIP

panic 会发生在如果 chunk_size 是 0.

chunks_exact

把一个切片分成若干个指定长度的切片,若剩余的元素长度不够,则直接丢弃

rust
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

参数

  • chunk_size:每一块的大小

返回值:返回一个ChunksExact迭代器

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for chunk in v.chunks_exact(2) {
        println!("{:?}", chunk);
    }
    /*
        [1, 2]
    	[3, 4]
     */
}

panic

panic 会发生在如果 chunk_size 是 0.

chunks_exact_mut

把一个切片分成若干个指定长度的切片的可变引用,若剩余的元素长度不够,则直接丢弃

rust
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

参数

  • chunk_size:每一个块的大小

返回值:返回一个ChunksExactMut迭代器

rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    for chunk in v.chunks_exact_mut(2) {
        chunk[0] += 1;
        println!("{:?}", chunk);
    }
    /*
       [2, 2]
       [3, 4]
    */
}

as_chunks

nightly-only

将一个切片中的元组按每个N长度分组,若剩余元素小于N,则另提出来作为另一个切片

rust
pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

泛型参数

  • N:每一块的长度

返回值:返回一个元素

  • 第一个元素是按N个元素分组的二维数组切片
  • 第二个元素是当剩余元素小于N时,单提出来的切片
rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    let (chunks, remainder) = v.as_chunks::<2>();

    println!("{:?}", chunks); // [[1, 2], [3, 4]]
    println!("{:?}", remainder); // [5]
}

当切片中元素正好能把N整除,也就是没有余数

rust
fn main() {
    let v = [1, 2, 3, 4, 5, 6];

    let (chunks, remainder) = v.as_chunks::<2>();

    println!("{:?}", chunks); // [[1, 2], [3, 4], [5, 6]]
    println!("{:?}", remainder); // []
}

panics

如果 N 为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。

as_chunks_mut

nightly-only

将一个切片中的元组按每个N长度分组,若剩余元素小于N,则另提出来作为另一个切片

每个切片都是可变引用

rust
pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

泛型参数

  • N:每一块的长度

返回值:返回一个元素

  • 第一个元素是按N个元素分组的二维数组切片的可变引用
  • 第二个元素是当剩余元素小于N时,单提出来的切片的可变引用
rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    let (chunks, remainder) = v.as_chunks_mut::<2>();

    println!("{:?}", chunks); // [[1, 2], [3, 4]]
    println!("{:?}", remainder); // [5]

    // 可以被修改
    for chunk in &mut *chunks {
        chunk[0] += 1;
        chunk[1] += 1;
    }

    remainder[0] += 1;

    println!("{:?}", chunks); // [[2, 3], [4, 5]]
    println!("{:?}", remainder); // [6]
}

as_chunks_unchecked

nightly-only

在不检查错误的情况下,把一个切片分为若干个长度为N的小切片

rust
pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

泛型参数

  • N:每一块的长度

返回值:返回被拆分为N个元素的二维数组切片

rust
fn main() {
    let v = [1, 2, 3, 4, 5, 6];

    unsafe {
        let chunks = v.as_chunks_unchecked::<2>();
        println!("{:?}", chunks);		// [[1, 2], [3, 4], [5, 6]]
    }
}

若剩余元素不足以满足N长度的数组切片,则会panic

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    unsafe {
        let chunks = v.as_chunks_unchecked::<2>(); // panic
    }
}

Safty

只能在以下情况下调用

  • 切片精确地分为 N 个元素块 (也称为 self.len() % N == 0)。
  • N != 0.

as_chunks_unchecked_mut

nightly-only

在不检查错误的情况下,把一个切片分为若干个长度为N的小切片的可变引用

rust
pub unsafe fn as_chunks_unchecked_mut<const N: usize>(
    &mut self
) -> &mut [[T; N]]

泛型参数

  • N:每一块的长度

返回值:返回被拆分为N个元素的二维数组切片的可变引用

rust
fn main() {
    let mut v = [1, 2, 3, 4, 5, 6];

    unsafe {
        let chunks = v.as_chunks_unchecked_mut::<2>();
        println!("{:?}", chunks); // [[1, 2], [3, 4], [5, 6]]

        for chunk in &mut *chunks {
            chunk[0] += 1;
            chunk[1] += 1;
        }

        println!("{:?}", chunks); // [[2, 3], [4, 5], [6, 7]]
    }
}

同样若剩余元素不足以满足N长度的数组切片,则会panic

rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    unsafe {
        let chunks = v.as_chunks_unchecked_mut::<2>();
        println!("{:?}", chunks); // panic
    }
}

Safty

只能在以下情况下调用

  • 切片精确地分为 N 个元素块 (也称为 self.len() % N == 0)。
  • N != 0.

as_rchunks

从切片的末尾开始,将切片分成 N 个元素数组的切片,然后将其长度严格小于 N 的其余切片分为另一个切片。nightly-only

rust
pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

泛型参数

  • N:每一块的长度

返回值:返回一个元组

  • 第一个元素为剩余元素所组成的切片
  • 第二个元素为从后往前,按照长度为N,切分的一个二维数组切片
rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    let chunks = v.as_rchunks::<2>();
    println!("{:?}", chunks); // ([1], [[2, 3], [4, 5]])
}

panics

如果 N 为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。

as_rchunks_mut

nightly-only

从切片的末尾开始,将切片分成 N 个元素数组的切片的可变引用

然后将其长度严格小于 N 的其余切片分为另一个切片的可变引用。

rust
pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

泛型参数

  • N:每一块的长度

返回值:返回一个元组

  • 第一个元素为剩余元素所组成的切片的可变引用
  • 第二个元素为从后往前,按照长度为N,切分的一个二维数组切片的可变引用
rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    let (remainder, chunks) = v.as_rchunks_mut::<2>();
    println!("{:?}", remainder ); // [1]
    println!("{:?}", chunks); // [[2, 3], [4, 5]]

    for r in &mut *remainder {
        *r += 1;
    }

    for chunk in &mut *chunks {
        chunk[0] += 1;
        chunk[1] += 1;
    }

    println!("{:?}", remainder); // [2]
    println!("{:?}", chunks); // [[3, 4], [5, 6]]
}

Panic

如果 N 为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。

array_chunks

nightly-only

把一个切片分成若干个长度为N的切片,若剩余的元素长度不够,则直接丢弃

此方法与 chunks_exact 等效为 const 泛型。

rust
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

泛型参数

  • N:每个块的长度,大小

返回值:返回被切割为指定长度的二维数组

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for chunk in v.array_chunks::<2>() {
        println!("{:?}", chunk); 
        /*
        	[1,2],
        	[3,4]
        */
    }
}

panics

如果 N 为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。

array_chunks_mut

nightly-only

把一个切片分成若干个长度为N的切片的可变引用,若剩余的元素长度不够,则直接丢弃

rust
pub unsafe fn as_chunks_unchecked_mut<const N: usize>(
    &mut self
) -> &mut [[T; N]]

泛型参数

  • N:每个块的长度,大小

返回值:返回被切割为指定长度的二维数组的可变引用

rust
let mut v = [1, 2, 3, 4];

for chunk in v.array_chunks_mut::<2>() {
    chunk[0] += 10;
}

println!("{:?}", v);

windows

传入一个长度n,每次先把n个长度元素放进一个数组切片中,然后往后滑一步,再依次把n个长度元素放进一个数组切片中

rust
pub fn windows(&self, size: usize) -> Windows<'_, T>

参数

  • size:一个长度,规定每个小数组切片中的元素数

返回值:返回一个std::slice::Windows迭代器

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for w in v.windows(2) {
        println!("{:?}", w);
    }
}
/*
 	[1, 2]
    [2, 3]
    [3, 4]
    [4, 5]
*/

如果切片短于 size

rust
fn main() {
    let slice = ['f', 'o', 'o'];
    let mut iter = slice.windows(4);
    println!("{:#?}", iter.next());  // None
}

panic

panic 会发生在如果 size 是 0.

array_windows

传入一个长度N,每次先把N个长度元素放进一个数组切片中,然后往后滑一步,再依次把N个长度元素放进一个数组切片中

windows()效果一样,只不过array_windowswindows的泛型参数版本

rust
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

泛型参数

  • N:一个长度,规定每个小数组切片中的元素数

返回值:返回重叠 N 元素的迭代器 windows。

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for w in v.array_windows::<2>() {
        println!("{:?}", w);
    }
}

/*
    [1, 2]
    [2, 3]
    [3, 4]
    [4, 5]
*/

panics

如果 N 为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。

rchunks

把一个切片从末尾开始往前,一次性选取chunk_size个元素,在这chunk_size个元素中,从前往后放入一个数组切片中,最后组成一个二维数组

若剩余的元素小于指定长度,则最后一块的长度为剩余元素数

rust
pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

参数

  • chunk_size:块的大小,规定每个小数组中的元素数

返回值:返回一个RChunks迭代器,其中的迭代项为每次选取的小数组

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for chunk in v.rchunks(2) {
        println!("{:?}", chunk);
    }

	/*
		[4, 5]
		[2, 3]
		[1]
	 */
}

panics

panic 会发生在如果 chunk_size 是 0.

rchunks_mut

把一个切片从末尾开始往前,一次性选取chunk_size个元素,在这chunk_size个元素中,从前往后放入一个数组切片中,最后组成一个二维数组的可变引用

若剩余的元素小于指定长度,则最后一块的长度为剩余元素数

rust
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

参数

  • chunk_size:块的大小,规定每个小数组中的元素数

返回值:返回一个RChunksMut迭代器,其中的迭代项为每次选取的小数组的可变引用

rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    for chunk in v.rchunks_mut(2) {
        chunk[0] += 1;
        println!("{:?}", chunk);
    }

    /*
       [5, 5]
       [6, 3]
       [1]
    */
}

rchunks_exact

把一个切片从末尾开始往前,一次性选取chunk_size个元素,在这chunk_size个元素中,从前往后放入一个数组切片中,最后组成一个二维数组

若剩余的元素小于指定长度,则直接丢弃剩余元素

rust
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

参数

  • chunk_size:块的大小,规定每个小数组中的元素数

返回值:返回一个RChunksExact迭代器,其中的迭代项为每次选取的小数组

rust
fn main() {
    let v = [1, 2, 3, 4, 5];

    for chunk in v.rchunks_exact(2) {
        println!("{:?}", chunk);
    }

    /*
       [4, 5]
       [5, 3]
    */
    
    // 1被丢弃
}

rchunks_exact_mut

把一个切片从末尾开始往前,一次性选取chunk_size个元素,在这chunk_size个元素中,从前往后放入一个数组切片中,最后组成一个二维数组的可变引用

若剩余的元素小于指定长度,则直接丢弃剩余元素

rust
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

参数

  • chunk_size:块的大小,规定每个小数组中的元素数

返回值:返回一个RChunksExactMut迭代器,其中的迭代项为每次选取的小数组的可变引用

rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];

    for chunk in v.rchunks_exact_mut(2) {
        chunk[0] += 1;
        println!("{:?}", chunk);
    }

    /*
      	[5, 5]
		[3, 3]
    */
}

group_by

nightly-only

返回在切片上使用迭代器生成迭代器的迭代器,这些谓词使用谓词将它们分隔开。

谓词在紧随其后的两个元素上调用,这意味着谓词在 slice[0]slice[1] 上调用,然后在 slice[1]slice[2] 上调用,依此类推。

rust
pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F> ⓘ
where
    F: FnMut(&T, &T) -> bool,

参数

  • pred:谓词

返回值:返回一个GroupBy

rust
#![feature(slice_group_by)]

let slice = &[1, 1, 1, 3, 3, 2, 2, 2];

let mut iter = slice.group_by(|a, b| a == b);

assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);

此方法可用于提取排序的子切片:

rust
#![feature(slice_group_by)]

let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];

let mut iter = slice.group_by(|a, b| a <= b);

assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
assert_eq!(iter.next(), None);

group_by_mut

nightly-only

返回在切片上使用谓词将其分离的迭代器,以生成不重叠的可变元素游程。

谓词在紧随其后的两个元素上调用,这意味着谓词在 slice[0]slice[1] 上调用,然后在 slice[1]slice[2] 上调用,依此类推。

rust
pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F> ⓘ
where
    F: FnMut(&T, &T) -> bool,

参数

  • pred:谓词

返回值:返回一个GroupByMut

rust
#![feature(slice_group_by)]

let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];

let mut iter = slice.group_by_mut(|a, b| a == b);

assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next(), Some(&mut [3, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
assert_eq!(iter.next(), None);

此方法可用于提取排序的子切片:

rust
#![feature(slice_group_by)]

let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];

let mut iter = slice.group_by_mut(|a, b| a <= b);

assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
assert_eq!(iter.next(), None);

split_at

在索引处将一个切片分为两个。

第一个将包含 [0, mid) 的所有索引 (不包括索引 mid 本身),第二个将包含 [mid, len) 的所有索引 (不包括索引 len 本身)。

rust
pub fn split_at(&self, mid: usize) -> (&[T], &[T])

参数

  • mid:分界处的索引,分界左边包含mid,右边不包含

返回值:返回被切分两半后组成的元组

  • 第一个元素为前半部分切片
  • 第一个元素为后半部分切片
rust
let v = [1, 2, 3, 4, 5, 6];

{
   let (left, right) = v.split_at(0);
   assert_eq!(left, []);
   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}

{
    let (left, right) = v.split_at(2);
    assert_eq!(left, [1, 2]);
    assert_eq!(right, [3, 4, 5, 6]);
}

{
    let (left, right) = v.split_at(6);
    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
    assert_eq!(right, []);
}

split_at_mut

在索引处将一个可变切片分成两个。

第一个将包含 [0, mid) 的所有索引 (不包括索引 mid 本身),第二个将包含 [mid, len) 的所有索引 (不包括索引 len 本身)。

rust
pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

参数

  • mid:分界处的索引,分界左边包含mid,右边不包含

返回值:返回被切分两半后组成的元组

  • 第一个元素为前半部分切片的可变引用
  • 第一个元素为后半部分切片的可变引用
rust
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.split_at_mut(2);
assert_eq!(left, [1, 0]);
assert_eq!(right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);

TIP

如果为 mid > len,就会出现 panics。

split_at_unchecked

nightly-only

在索引处将一个切片分为两个,而无需进行边界检查。

第一个将包含 [0, mid) 的所有索引 (不包括索引 mid 本身),第二个将包含 [mid, len) 的所有索引 (不包括索引 len 本身)。

有关安全的选择,请参见 split_at

rust
pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

参数

  • mid:分界处的索引,左不包含,右包含

返回值:返回被切分两半后组成的元组

rust
#![feature(slice_split_at_unchecked)]

let v = [1, 2, 3, 4, 5, 6];

unsafe {
   let (left, right) = v.split_at_unchecked(0);
   assert_eq!(left, []);
   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}

unsafe {
    let (left, right) = v.split_at_unchecked(2);
    assert_eq!(left, [1, 2]);
    assert_eq!(right, [3, 4, 5, 6]);
}

unsafe {
    let (left, right) = v.split_at_unchecked(6);
    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
    assert_eq!(right, []);
}

TIP

即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。调用者必须确保 0 <= mid <= self.len().

split_at_mut_unchecked

nightly-only

在索引处将一个切片分为两个,而无需进行边界检查。

第一个将包含 [0, mid) 的所有索引 (不包括索引 mid 本身),第二个将包含 [mid, len) 的所有索引 (不包括索引 len 本身)。

有关安全的选择,请参见 split_at

rust
pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

参数

  • mid:分界处的索引,左不包含,右包含

返回值:返回被切分两半后组成的元组

  • 第一个元素为前半部分切片的可变引用
  • 第一个元素为后半部分切片的可变引用
rust
#![feature(slice_split_at_unchecked)]

let v = [1, 2, 3, 4, 5, 6];

unsafe {
   let (left, right) = v.split_at_unchecked(0);
   assert_eq!(left, []);
   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}

unsafe {
    let (left, right) = v.split_at_unchecked(2);
    assert_eq!(left, [1, 2]);
    assert_eq!(right, [3, 4, 5, 6]);
}

unsafe {
    let (left, right) = v.split_at_unchecked(6);
    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
    assert_eq!(right, []);
}

TIP

即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。调用者必须确保 0 <= mid <= self.len().

split_array_ref

nightly-only

将一个切片分成一个数组和一个索引处的剩余切片。

该数组将包含来自 [0, N) 的所有索引 (不包括索引 N 本身),并且切片将包含来自 [N, len) 的所有索引 (不包括索引 len 本身)。

rust
pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])

泛型参数

  • N:分界线的索引,左不包含,右包含

返回值:返回一个元组,第一个元素为被切割的数组,第二个元素为剩余的切片

rust
#![feature(split_array)]

let v = &[1, 2, 3, 4, 5, 6][..];

{
   let (left, right) = v.split_array_ref::<0>();
   assert_eq!(left, &[]);
   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}

{
    let (left, right) = v.split_array_ref::<2>();
    assert_eq!(left, &[1, 2]);
    assert_eq!(right, [3, 4, 5, 6]);
}

{
    let (left, right) = v.split_array_ref::<6>();
    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
    assert_eq!(right, []);
}

panic

如果 N > len,就会出现 panics。

split_array_mut

nightly-only

将一个可变切片分成一个数组和一个索引处的剩余切片。

该数组将包含来自 [0, N) 的所有索引 (不包括索引 N 本身),并且切片将包含来自 [N, len) 的所有索引 (不包括索引 len 本身)。

rust
pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T])

泛型参数

  • N:分界线的索引,左不包含,右包含

返回值:返回一个元组,第一个元素为被切割的数组的可变引用,第二个元素为剩余的切片的可变引用

rust
#![feature(split_array)]

let mut v = &mut [1, 0, 3, 0, 5, 6][..];
let (left, right) = v.split_array_mut::<2>();

assert_eq!(left, &mut [1, 0]);
assert_eq!(right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);

Panic

如果 N > len,就会出现 panics。

rsplit_array_ref

nightly-only

将一个切片分成一个数组和一个从末尾开始的索引处的剩余切片。

该切片将包含来自 [0, len - N) 的所有索引 (不包括索引 len - N 本身),而数组将包含来自 [len - N, len) 的所有索引 (不包括索引 len 本身)。

rust
pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])

泛型参数

  • N:分界线的索引,左不包含,右包含

返回值:返回一个元组,第一个元素为剩余的切片,第二个元素为被切割的数组

rust
#![feature(split_array)]

let v = &[1, 2, 3, 4, 5, 6][..];

{
   let (left, right) = v.rsplit_array_ref::<0>();
   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
   assert_eq!(right, &[]);
}

{
    let (left, right) = v.rsplit_array_ref::<2>();
    assert_eq!(left, [1, 2, 3, 4]);
    assert_eq!(right, &[5, 6]);
}

{
    let (left, right) = v.rsplit_array_ref::<6>();
    assert_eq!(left, []);
    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
}

rsplit_array_mut

nightly-only

将一个可变切片分成一个数组和一个从末尾开始的索引处的剩余切片。

该切片将包含来自 [0, len - N) 的所有索引 (不包括索引 N 本身),而数组将包含来自 [len - N, len) 的所有索引 (不包括索引 len 本身)。

rust
pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N])

泛型参数

  • N:分界线的索引,左不包含,右包含

返回值:返回一个元组,第一个元素为剩余的切片,第二个元素为被切割的数组

rust
#![feature(split_array)]

let mut v = &mut [1, 0, 3, 0, 5, 6][..];
let (left, right) = v.rsplit_array_mut::<4>();
assert_eq!(left, [1, 0]);
assert_eq!(right, &mut [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);

panics

如果 N > len,就会出现 panics。

spllit

根据谓词,把一个数组切片,分割为两个数组切片,并放进一个数组组合成一个二维数组, 匹配的元素不包含在子切片中。

rust
pub fn split<F>(&self, pred: F) -> Split<'_, T, F> 
where
    F: FnMut(&T) -> bool,

参数

  • pred:谓词,根据此函数的返回值作为分割的分界线

返回值:返回一个Split迭代器,迭代项为被分割的前后两个数组

rust
let slice = [10, 40, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());

spllit_mut

根据谓词,把一个数组切片,分割为两个数组切片,并放进一个数组组合成一个二维数组。 匹配的元素不包含在子切片中。

rust
pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F> ⓘ
where
    F: FnMut(&T) -> bool,

参数

  • pred:谓词,根据此函数的返回值作为分割的分界线

返回值:返回一个SplitMut迭代器,迭代项为被分割的前后两个数组

rust
let mut v = [10, 40, 30, 20, 60, 50];

for group in v.split_mut(|num| *num % 3 == 0) {
    group[0] = 1;
}
assert_eq!(v, [1, 40, 30, 1, 60, 1]);

split_inclusive

返回由与 pred 匹配的元素分隔的子切片上的迭代器。 匹配的元素包含在上一个子切片的末尾作为终止符。

rust
pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F> 
where
    F: FnMut(&T) -> bool,

参数

  • pred:谓词函数

返回值:返回一个SplitInclusive

rust
let slice = [10, 40, 33, 20];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());

如果切片的最后一个元素匹配,则该元素将被视为前一个切片的终止符。

该切片将是迭代器返回的最后一个项目。

rust
let slice = [3, 10, 40, 33];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[3]);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert!(iter.next().is_none());

split_inclusive_mut

返回由匹配 pred 的元素分隔的可变子切片上的迭代器。 匹配的元素作为终止符包含在先前的子切片中。

rust
pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F> 
where
    F: FnMut(&T) -> bool,

参数

  • pred:谓词,根据此函数返回值切割数组

返回值

rust
fn main() {
    let mut v = [1, 0, 2, 0, 3];

    for chunk in v.split_inclusive_mut(|&x| x == 0) {
        println!("{:?}", chunk);
    }

	/*
	[1, 0]
	[2, 0]
	[3]
	 */
}

rsplit

在子切片上返回一个迭代器,该迭代器由与 pred 匹配的元素分隔,从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

rust
pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F> 
where
    F: FnMut(&T) -> bool,

参数

  • pred:谓词,根据此函数返回值切割数组

返回值:返回一个RSplit迭代器,迭代项为切割的数组

rust
let slice = [11, 22, 33, 0, 44, 55];
let mut iter = slice.rsplit(|num| *num == 0);

assert_eq!(iter.next().unwrap(), &[44, 55]);
assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
assert_eq!(iter.next(), None);

split() 一样,如果第一个或最后一个元素匹配,则空切片将是迭代器返回的第一个 (或最后一个) 项。

rust
let v = &[0, 1, 1, 2, 3, 5, 8];
let mut it = v.rsplit(|n| *n % 2 == 0);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next().unwrap(), &[3, 5]);
assert_eq!(it.next().unwrap(), &[1, 1]);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next(), None);

rsplit_mut

在子切片上返回一个迭代器,该迭代器由与 pred 匹配的元素分隔,从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

rust
pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F> ⓘ
where
    F: FnMut(&T) -> bool,

参数

  • prep:谓词,根据此函数返回值切割数组

返回值:返回一个RSplitMut迭代器,迭代项为切割的数组的可变引用

rust
let mut v = [100, 400, 300, 200, 600, 500];

let mut count = 0;
for group in v.rsplit_mut(|num| *num % 3 == 0) {
    count += 1;
    group[0] = count;
}
assert_eq!(v, [3, 400, 300, 2, 600, 1]);

splitn

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,限于最多返回 n 项。 匹配的元素不包含在子切片中

返回的最后一个元素 (如果有) 将包含切片的其余部分。

rust
pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F> ⓘ
where
    F: FnMut(&T) -> bool,

参数

  • n:限制被切割的份数
  • pred:谓词函数

返回值:返回一个SplitN迭代器,迭代项为切割的数组的可变引用

按 3 的整数倍数 (即 [10, 40][20, 60, 50]) 打印一次切片分割:

rust
fn main() {
    let v = [10, 40, 30, 20, 60, 50];

    for group in v.splitn(2, |num| *num % 3 == 0) {
        println!("{group:?}");
    }
    // 	[10, 40]
    //  [20, 60, 50]
}

splitn_mut

返回由匹配 pred 的元素分隔的子切片的迭代器,限制为最多返回 n 项。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

rust
pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where
    F: FnMut(&T) -> bool,

参数

  • n:限制被切割的份数
  • pred:谓词函数,根据此函数返回值切割数组

返回值:返回一个SplitNMut迭代器,迭代项为切割的数组的可变引用

rust
let mut v = [10, 40, 30, 20, 60, 50];

for group in v.splitn_mut(2, |num| *num % 3 == 0) {
    group[0] = 1;
}
assert_eq!(v, [1, 40, 30, 1, 60, 50]);

rsplitn

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,最多只能返回 n 项。 该操作从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

rust
pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F> ⓘ
where
    F: FnMut(&T) -> bool,

参数

  • n:限制被切割的份数
  • pred:谓词函数,根据此函数返回值切割数组

返回值:返回一个RSplitN迭代器,迭代项为切割的数组的可变引用

rust
let v = [10, 40, 30, 20, 60, 50];

for group in v.rsplitn(2, |num| *num % 3 == 0) {
    println!("{group:?}");
}

rsplitn_mut

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,最多只能返回 n 项。 该操作从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

rust
pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where
    F: FnMut(&T) -> bool,

参数

  • n:限制被切割的份数
  • pred:谓词函数,根据此函数返回值切割数组

返回值:返回一个RSplitNMut迭代器,,迭代项为切割的数组的可变引用

rust
let mut s = [10, 40, 30, 20, 60, 50];

for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
    group[0] = 1;
}
assert_eq!(s, [1, 40, 30, 20, 60, 1]);

contains

如果切片包含具有给定值的元素,则返回 true

这个操作是 O(n)。

请注意,如果您有一个排序切片,binary_search 可能会更快。

rust
pub fn contains(&self, x: &T) -> bool
where
    T: PartialEq<T>,

参数

  • x:需要被判断是否包含的元素

返回值:根据提供的元素判断是否存在,返回bool值

rust
let v = [10, 40, 30];
assert!(v.contains(&30));
assert!(!v.contains(&50));

如果您没有 &T,但有其他一些可以与之比较的值 (例如,String 实现 PartialEq<str>),则可以使用 iter().any

rust
let v = [String::from("hello"), String::from("world")]; // `String` 切片
assert!(v.iter().any(|e| e == "hello")); // 用 `&str` 搜索
assert!(!v.iter().any(|e| e == "hi"));

starts_with

如果 needle 是切片的前缀,则返回 true

rust
pub fn starts_with(&self, needle: &[T]) -> bool
where
    T: PartialEq<T>,

参数

  • needle:一个切片,判断self是否以needle开头

返回值:返回bool值

rust
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));

如果 needle 为空切片,则始终返回 true

rust
let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));

end_with

如果 needle 是切片的后缀,则返回 true

rust
pub fn ends_with(&self, needle: &[T]) -> bool
where
    T: PartialEq<T>,

参数

  • needle:一个切片,判断self是否以needle结尾

返回值:返回bool值

rust
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));

如果 needle 为空切片,则始终返回 true

rust
let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));

strip_prefix

返回带有删除的前缀的子切片。

rust
pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where
    P: SlicePattern<Item = T> + ?Sized,
    T: PartialEq<T>,

参数

  • prefix:判断是否以此前缀开头

返回值

  • 如果切片以 prefix 开头,则返回前缀在 Some 中的子切片。 如果 prefix 为空,则只需返回原始切片。
  • 如果切片不是以 prefix 开头,则返回 None
rust
let v = &[10, 40, 30];
assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
assert_eq!(v.strip_prefix(&[50]), None);
assert_eq!(v.strip_prefix(&[10, 50]), None);

let prefix : &str = "he";
assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),Some(b"llo".as_ref()));

strip_suffix

返回删除后缀的子分片。

rust
pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where
    P: SlicePattern<Item = T> + ?Sized,
    T: PartialEq<T>,

参数

  • suffix:判断是否以此后缀结尾

返回值

  • 如果切片以 suffix 结尾,则返回后缀在 Some 中的子切片。 如果 suffix 为空,则只需返回原始切片。
  • 如果切片不以 suffix 结尾,则返回 None
rust
let v = &[10, 40, 30];
assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
assert_eq!(v.strip_suffix(&[50]), None);
assert_eq!(v.strip_suffix(&[50, 30]), None);

二分查找 在此切片中搜索给定元素。 如果切片没有排序,返回的结果是不确定的,没有意义。

另请参见 binary_search_bybinary_search_by_keypartition_point

rust
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
where
    T: Ord,

参数

  • x:需要查找的元素

返回值

  • 如果找到该值,则返回 Result::Ok,其中包含匹配元素的索引。 如果有多个匹配项,则可以返回任何一个匹配项。 索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。
  • 如果找不到该值,则返回 Result::Err,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。

查找一系列四个元素。 找到第一个,具有唯一确定的位置; 没有找到第二个和第三个; 第四个可以匹配 [1, 4] 中的任何位置。

rust
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

assert_eq!(s.binary_search(&13),  Ok(9));
assert_eq!(s.binary_search(&4),   Err(7));
assert_eq!(s.binary_search(&100), Err(13));
let r = s.binary_search(&1);
assert!(match r { Ok(1..=4) => true, _ => false, });

如果您想找到匹配项的整个范围,而不是任意匹配项,可以使用 partition_point 完成:

rust
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let low = s.partition_point(|x| x < &1);
assert_eq!(low, 1);
let high = s.partition_point(|x| x <= &1);
assert_eq!(high, 5);
let r = s.binary_search(&1);
assert!((low..high).contains(&r.unwrap()));

assert!(s[..low].iter().all(|&x| x < 1));
assert!(s[low..high].iter().all(|&x| x == 1));
assert!(s[high..].iter().all(|&x| x > 1));

// 对于未找到的东西,等项的 "range" 为空
assert_eq!(s.partition_point(|x| x < &11), 9);
assert_eq!(s.partition_point(|x| x <= &11), 9);
assert_eq!(s.binary_search(&11), Err(9));

如果要向已排序的 vector 插入项,同时保持排序顺序,请考虑使用 partition_point:

rust
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x < num);
// 以上等价于 `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);

binary_search_by

二分查找使用比较器函数搜索此切片。

比较器函数应返回一个命令代码,指示其参数是 LessEqual 还是 Greater 所需的目标。 如果切片未排序或比较器函数未实现与底层切片的排序顺序一致的顺序,则返回的结果是未指定的且无意义的。

另请参见 binary_searchbinary_search_by_keypartition_point

rust
pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where
    F: FnMut(&'a T) -> Ordering,

参数

  • f:一个闭包 / 函数,返回一个Ordering

返回值

  • 如果找到该值,则返回 Result::Ok,其中包含匹配元素的索引。如果有多个匹配项,则可以返回任何一个匹配项。 索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。
  • 如果找不到该值,则返回Result::Err,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。

查找一系列四个元素。找到第一个,具有唯一确定的位置; 没有找到第二个和第三个; 第四个可以匹配 [1, 4] 中的任何位置。

rust
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let seek = 13;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
let seek = 4;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
let seek = 100;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
let seek = 1;
let r = s.binary_search_by(|probe| probe.cmp(&seek));
assert!(match r { Ok(1..=4) => true, _ => false, });

binary_search_by_key

二分查找使用键提取函数搜索此切片。

假定按关键字对切片进行排序,例如使用相同的关键字提取函数对 sort_by_key 进行排序。 如果切片不按键排序,则返回结果未指定且无意义。

另请参见 binary_searchbinary_search_bypartition_point

rust
pub fn binary_search_by_key<'a, B, F>(
    &'a self,
    b: &B,
    f: F
) -> Result<usize, usize>
where
    F: FnMut(&'a T) -> B,
    B: Ord,

参数

  • b:需要查找的目标值
  • f:从切片元素中提取“用于比较的键”的函数

返回值

  • 如果找到该值,则返回Result::Ok,其中包含匹配元素的索引。 如果有多个匹配项,则可以返回任何一个匹配项。 索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。
  • 如果找不到该值,则返回Result::Err,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。

在成对的切片中按其第二个元素排序的一系列四个元素中查找。 找到第一个,具有唯一确定的位置; 没有找到第二个和第三个; 第四个可以匹配 [1, 4] 中的任何位置。

rust
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
         (1, 21), (2, 34), (4, 55)];

assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
let r = s.binary_search_by_key(&1, |&(a, b)| b);
assert!(match r { Ok(1..=4) => true, _ => false, });

sort_unstable

使用比较器函数对三元进行排序,但可能不保留相等元素的顺序。

rust
pub fn sort_unstable(&mut self)
where
    T: Ord,

示例

rust
let mut v = [-5, 4, 1, -3, 2];

v.sort_unstable();
assert!(v == [-5, -3, 1, 2, 4]);

sort_unstable_by

对数组进行排序,可以自定义排序函数中比较两个元素的逻辑

rust
pub fn sort_unstable_by<F>(&mut self, compare: F)
where
    F: FnMut(&T, &T) -> Ordering,

参数

  • compare:排序函数,函数中的两个参数表示待比较的元素,返回一个Ordering枚举,分别有以下几个变体
    • Ordering::Lessa < b
    • Ordering::Equala == b
    • Ordering::Greatera > b
rust
fn main() {
    let mut v = [3, 1, 4, 1, 5];

    v.sort_unstable_by(|a, b| b.cmp(a)); // 降序

    println!("{:?}", v);
}

多段排序

rust
#[derive(Debug)]
struct Person {
    name: &'static str,
    age: u8,
    score: i32,
}

fn main() {
    let mut people = vec![
        Person { name: "Alice", age: 30, score: 90 },
        Person { name: "Bob", age: 25, score: 95 },
        Person { name: "Carol", age: 30, score: 85 },
    ];

    people.sort_unstable_by(|a, b| {
        a.age.cmp(&b.age)
            .then(b.score.cmp(&a.score)) // 年龄相同,分数降序
    });

    println!("{:#?}", people);
}

sort_unstable_by_key

提供一个键,函数自动按照这个键进行排序

rust
pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where
    F: FnMut(&T) -> K,
    K: Ord,

参数

  • f:排序函数,返回一个Ord
    • 输入:切片中的一个元素
    • 输出:排序键(key)
rust
#[derive(Debug)]
struct Person {
    name: &'static str,
    age: u8,
}

fn main() {
    let mut people = vec![
        Person { name: "Alice", age: 30 },
        Person { name: "Bob", age: 25 },
        Person { name: "Carol", age: 27 },
    ];

    people.sort_unstable_by_key(|p| p.age);

    println!("{:#?}", people);
    
    /*
    	[
            Person { name: "Bob", age: 25 },
            Person { name: "Carol", age: 27 },
            Person { name: "Alice", age: 30 },
        ]
    */
}

按计算结果排序(非常常见)

rust
let mut v = [-3, 1, -2, 4];

v.sort_unstable_by_key(|&x| x.abs());

println!("{:?}", v); // [1, -2, -3, 4]

按字符串长度排序

rust
let mut words = ["hello", "hi", "goodbye"];

words.sort_unstable_by_key(|s| s.len());

println!("{:?}", words);
// ["hi", "hello", "goodbye"]

数字数组排序

rust
use std::cmp::Reverse;

let mut scores = [50, 80, 70];

scores.sort_unstable_by_key(|&s| Reverse(s));

println!("{:?}", scores); // [80, 70, 50]

select_nth_unstable

在一个数组中,找到按顺序排在第index个的元素

rust
ub fn select_nth_unstable(
    &mut self,
    index: usize
) -> (&mut [T], &mut T, &mut [T])
where
    T: Ord,

参数

  • index:一个索引

返回值:返回一个三个元素的元组,分别命名为leftcenterright

  • left:一个数组的可变引用,里面是比center小的所有元素,不保证顺序
  • center:找到的第index小的元素
  • right:一个数组的可变引用,里面是比center大的所有元素,不保证顺序
rust
fn main() {
    let mut v = [3, 1, 4, 1, 5, 9, 2];

    let (left, nth, right) = v.select_nth_unstable(2);

    println!("left:  {:?}", left);
    println!("nth:   {}", nth);
    println!("right: {:?}", right);
}

TIP

index >= len() 时为 Panics,这意味着在空片上始终为 panics。

select_nth_unstable_by

根据自定义排序函数,找到按顺序排在第index个的元素

rust
pub fn select_nth_unstable_by<F>(
    &mut self,
    index: usize,
    compare: F
) -> (&mut [T], &mut T, &mut [T])
where
    F: FnMut(&T, &T) -> Ordering,

参数

  • index:一个索引
  • compare:一个比较函数,函数中的两个参数表示待比较的元素,返回一个Ordering枚举,分别有以下几个变体
    • Ordering::Lessa < b
    • Ordering::Equala == b
    • Ordering::Greatera > b

返回值:返回一个三个元素的元组,分别命名为leftcenterright

  • left:一个数组的可变引用,里面是比center小的所有元素,不保证顺序
  • center:找到的第index小的元素
  • right:一个数组的可变引用,里面是比center大的所有元素,不保证顺序
rust
fn main() {
    let mut v = [3, 1, 4, 1, 5];

    let (_left, nth, _right) =
        v.select_nth_unstable_by(1, |a, b| b.cmp(a)); // 降序

    println!("second largest = {}", nth);		// second largest = 4
}

多字段比较示例

rust
#[derive(Debug)]
struct Item {
    a: i32,
    b: i32,
}

fn main() {
    let mut items = vec![
        Item { a: 1, b: 3 },
        Item { a: 2, b: 1 },
        Item { a: 1, b: 2 },
    ];

    let (_l, nth, _r) = items.select_nth_unstable_by(1, |x, y| {
        x.a.cmp(&y.a)
            .then_with(|| x.b.cmp(&y.b))
    });

    println!("{:?}", nth);
}

select_nth_unstable_by_key

某个 key ,找到按顺序排在第index个的元素

rust
pub fn select_nth_unstable_by_key<K, F>(
    &mut self,
    index: usize,
    f: F
) -> (&mut [T], &mut T, &mut [T])
where
    F: FnMut(&T) -> K,
    K: Ord,

参数

  • index:一个索引
  • f:排序函数,函数中的一个参数为当前项的值,返回一个Ord

返回值:返回一个三个元素的元组,分别命名为leftcenterright

  • left:一个数组的可变引用,里面是比center小的所有元素,不保证顺序
  • center:找到的第index小的元素
  • right:一个数组的可变引用,里面是比center大的所有元素,不保证顺序
rust
#[derive(Debug)]
struct Person {
    name: &'static str,
    age: u8,
}

fn main() {
    let mut people = vec![
        Person { name: "Alice", age: 20 },
        Person { name: "Bob", age: 35 },
        Person { name: "Carol", age: 30 },
        Person { name: "Dave", age: 25 },
    ];

    let (_left, median, _right) =
        people.select_nth_unstable_by_key(2, |p| p.age);

    println!("median = {:?}", median);
}

按计算结果排序(绝对值)

rust
fn main() {
    let mut v = [-5, -1, 3, -2];

    let (_l, nth, _r) =
        v.select_nth_unstable_by_key(2, |&x| x.abs());

    println!("{}", nth); // -2
}

partition_dedup

nightly-only

根据 PartialEq trait 实现,将所有连续的多余重复元素挤出来,放入另一个数组

rust
pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where
    T: PartialEq<T>,

返回值:返回一个元组

  • 第一个元素:不包含连续的重复元素的数组
  • 第二个元素:包含没有指定顺序的所有重复项
rust
#![feature(slice_partition_dedup)]

let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];

let (dedup, duplicates) = slice.partition_dedup();

assert_eq!(dedup, [1, 2, 3, 2, 1]);
assert_eq!(duplicates, [2, 3, 1]);

partition_dedup_by

nightly-only

根据自定义函数,将所有连续的多余重复元素挤出来,放入另一个数组

rust
pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where
    F: FnMut(&mut T, &mut T) -> bool,

参数

  • same_bucket:自定义重复逻辑的函数
    • 返回true:两个元素被视为“相同”,后一个会被移除
    • 返回false:保留元素

返回值:返回一个元组

  • 第一个元素:不包含连续的重复元素的数组
  • 第二个元素:包含没有指定顺序的所有重复项
rust
fn main() {
    let mut words = ["foo", "Foo", "bar", "BAR"];

    let (dedup, _) = words.partition_dedup_by(|a, b| {
        a.eq_ignore_ascii_case(b)
    });

    println!("{:?}", dedup);  // ["foo", "bar"]
}

结构体字段级去重

rust
#[derive(Debug)]
struct Item(i32);

let mut v = [Item(1), Item(1), Item(2)];

let (dedup, _) = v.partition_dedup_by(|a, b| a.0 == b.0);

println!("{:?}", dedup);
// [Item(1), Item(2)]

partition_dedup_by_key

nightly-only

根据提供的key,将所有连续的多余重复元素挤出来,放入另一个数组

rust
pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where
    F: FnMut(&mut T) -> K,
    K: PartialEq<K>,

参数

  • key:提取用于比较的 key

返回值:返回一个元组

  • 第一个元素:不包含连续的重复元素的数组
  • 第二个元素:包含没有指定顺序的所有重复项
rust
#[derive(Debug)]
struct Log {
    level: &'static str,
    msg: &'static str,
}

fn main() {
    let mut logs = vec![
        Log { level: "INFO", msg: "a" },
        Log { level: "INFO", msg: "b" },
        Log { level: "ERROR", msg: "c" },
    ];

    let (dedup, _) = logs.partition_dedup_by_key(|log| log.level);

    println!("{:#?}", dedup);
    /*
    	[
            Log { level: "INFO", msg: "a" },
            Log { level: "ERROR", msg: "c" },
        ]
    */
}

按绝对值去重

rust
fn main() {
    let mut v = [-1, 1, -2, 2, 3];

    let (dedup, _) = v.partition_dedup_by_key(|&x| x.abs());

    println!("{:?}", dedup);  // [-1, -2, 3]
}

rotate_left

把前n个元素,移动到末尾追加

rust
pub fn rotate_left(&mut self, n: usize)

参数

  • n:代表前n个元素

返回值

rust
fn main() {
    let mut slice = [1, 2, 3, 4, 5];
    slice.rotate_left(2);
    println!("{:?}", slice); // [3, 4, 5, 1, 2]
}

rotate_right

把最后n个元素,移动到数组前面

rust
pub fn rotate_right(&mut self, n: usize)

参数

  • n:代表最后n个元素

返回值

rust
fn main() {
    let mut slice = [1, 2, 3, 4, 5];
    slice.rotate_right(2);
    println!("{:?}", slice); // [4, 5, 1, 2, 3]
}

fill

填充数组,填充的值是通过Clone克隆过来的值

rust
pub fn fill(&mut self, value: T)
where
    T: Clone,

参数

  • value:需要填充的值,实现了Clone trait
rust
fn main() {
    let mut slice = [0, 0, 0, 0, 0];
    slice.fill(2);
    println!("{:?}", slice); // [2,2,2,2,2]
}

fill_with

通过自定义函数的返回值填充数组

rust
pub fn fill_with<F>(&mut self, f: F)
where
    F: FnMut() -> T,

参数

  • f:此函数的返回值会被填充到数组中
rust
fn main() {
    let mut v = [1, 2, 3, 4, 5];
    v.fill_with(|| 666);

    println!("{:?}", v);  // [666, 666, 666, 666, 666]
}

如果要使用 Defaulttrait 生成值,则可以传递Default::default 作为参数。

rust
let mut buf = vec![1; 10];
buf.fill_with(Default::default);
assert_eq!(buf, vec![0; 10]);

clone_from_slice

将另一个切片,复制到self身上,两者的长度必须相同

目标切片的元素实现Clone Trait

rust
pub fn clone_from_slice(&mut self, src: &[T])
where
    T: Clone,

参数

  • src:目标切片,长度必须和self长度相同
rust
fn main() {
    let v = [1, 2, 3, 4, 5];
    let mut v2: [i32; 5] = [0, 0, 0, 0, 0];

    v2.clone_from_slice(&v);

    println!("{:#?}", v2); //  [1, 2, 3, 4, 5]
}

TIP

如果两个切片的长度不同,则此函数将为 panic。

copy_from_slice

将另一个切片,复制到self身上,两者的长度必须相同

目标切片的元素实现Copy Trait

rust
pub fn copy_from_slice(&mut self, src: &[T])
where
    T: Copy,

参数

  • src:目标切片,长度必须和self长度相同
rust
fn main() {
    let v = [1, 2, 3, 4, 5];
    let mut v2: [i32; 5] = [0, 0, 0, 0, 0];

    v2.copy_from_slice(&v);

    println!("{:#?}", v2); //  [1, 2, 3, 4, 5]
}

TIP

如果两个切片的长度不同,则此函数将为 panic。

copy_within

把切片中一段连续元素,复制到同一切片内的另一个位置,允许重叠

rust
pub fn copy_within<R>(&mut self, src: R, dest: usize)
where
    R: RangeBounds<usize>,
    T: Copy,

参数

  • src:源区间(要复制的范围)
  • dest:目标位置的起始索引
rust
fn main() {
    let mut v = [1, 2, 3, 4, 5, 6, 7];

    v.copy_within(2..5, 4);

    println!("{:?}", v);
}
原: [1, 2, 3, 4, 5, 6, 7]
src:       [3, 4, 5]
dest:
结果:[1, 2, 3, 4, 3, 4, 5]

swap_with_slice

把当前切片和另一个切片“逐元素交换”,长度必须相等,一次调用完成整块交换

rust
pub fn swap_with_slice(&mut self, other: &mut [T]

参数

  • other:被复制的切片
rust
fn main() {
    let mut a = [1, 2, 3];
    let mut b = [4, 5, 6];

    a.swap_with_slice(&mut b);

    println!("a = {:?}", a); // [4, 5, 6]
    println!("b = {:?}", b); // [1, 2, 3]
}

TIP

如果两个切片的长度不同,则此函数将为 panic。

align_to

将切片转换为其他类型的切片,以确保保持类型的对齐。

此方法将切片分为三个不同的切片:前缀,正确对齐的新类型的中间切片和后缀切片。 没有具体说明切片是如何分割的; 中间部分可能比必要的要小。 但是,如果这未能返回最大中间部分,那是因为代码在性能无关紧要的上下文中运行,例如试图查找对齐错误的消毒程序。

在默认 (调试或发布) 执行中运行的常规代码返回最大的中间部分。

当输入元素 T 或输出元素 U 的大小为零时,此方法无用,并且将返回原始切片而不拆分任何内容。

rust
pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

泛型参数

  • U:一个类型

返回值:返回一个元组

  • prefix:头部未对齐数据
  • aligned:对齐后的“主数据”
  • suffix:尾部未对齐数据
rust
fn main() {
    let v: [u8; 10] = [0; 10];

    unsafe{
        let (pre, aligned, suf) = v.align_to::<u32>();

        println!("pre.len() = {}", pre.len());  // pre.len() = 2
        println!("aligned.len() = {}", aligned.len());  // aligned.len() = 1   // 4 bytes
        println!("suf.len() = {}", suf.len());  // suf.len() = 4
    }
}

TIP

对于返回的中间切片中的元素,此方法本质上是 transmute,因此,与 transmute::<T, U> 有关的所有常见警告也适用于此。

align_to_mut

将不扩散切片转换为另一种类型的不扩散切片,确保保持类型的对齐。

此方法将切片分为三个不同的切片:前缀,正确对齐的新类型的中间切片和后缀切片。 没有具体说明切片是如何分割的; 中间部分可能比必要的要小。 但是,如果这未能返回最大中间部分,那是因为代码在性能无关紧要的上下文中运行,例如试图查找对齐错误的消毒程序。

在默认 (调试或发布) 执行中运行的常规代码返回最大的中间部分。

当输入元素 T 或输出元素 U 的大小为零时,此方法无用,并且将返回原始切片而不拆分任何内容。

rust
pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

泛型参数

  • N:一个类型

返回值:返回一个元组

  • prefix:头部未对齐数据
  • aligned:对齐后的“主数据”
  • suffix:尾部未对齐数据
rust
unsafe {
    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
    // less_efficient_algorithm_for_bytes(prefix);
    // more_efficient_algorithm_for_aligned_shorts(shorts);
    // less_efficient_algorithm_for_bytes(suffix);
}

TIP

对于返回的中间切片中的元素,此方法本质上是 transmute,因此,与 transmute::<T, U> 有关的所有常见警告也适用于此

as_simd

将切片分成前缀、中间对齐的 SIMD 类型和后缀。

这是一个围绕 slice::align_to 的安全包装器,因此具有与该方法相同的弱后置条件。 您只需要保证 self.len() == prefix.len() + middle.len() * LANES + suffix.len()

值得注意的是,以下所有情况都是可能的:

  • prefix.len() >= LANES.
  • middle.is_empty() 尽管 self.len() >= 3 * LANES
  • suffix.len() >= LANES.

也就是说,这是一个安全的方法,所以如果您只编写安全的代码,那么这最多会导致不正确的逻辑,而不是不健全的。

rust
pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where
    Simd<T, LANES>: AsRef<[T; LANES]>,
    T: SimdElement,
    LaneCount<LANES>: SupportedLaneCount,

返回值:返回一个元组

rust
#![feature(portable_simd)]
use core::simd::SimdFloat;

let short = &[1, 2, 3];
let (prefix, middle, suffix) = short.as_simd::<4>();
assert_eq!(middle, []); // 中间没有足够的元素

// 它们可能以任何可能的方式在前缀和后缀之间拆分
let it = prefix.iter().chain(suffix).copied();
assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);

fn basic_simd_sum(x: &[f32]) -> f32 {
    use std::ops::Add;
    use std::simd::f32x4;
    let (prefix, middle, suffix) = x.as_simd();
    let sums = f32x4::from_array([
        prefix.iter().copied().sum(),
        0.0,
        0.0,
        suffix.iter().copied().sum(),
    ]);
    let sums = middle.iter().copied().fold(sums, f32x4::add);
    sums.reduce_sum()
}

let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);

TIP

如果 SIMD 类型的大小不同于标量的 LANES 倍,就会出现 panic。

在撰写本文时,Simd<T, LANES> 上的 trait 限制使这种情况永远不会发生,因为仅支持 2 的幂的 lanes 数。 有可能在未来的时候,这些限制可能会以某种方式取消,这样就有可能看到类似 LANES == 3 的 panics。

as_simd_mut

nightly-only

rust
source
pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where
    Simd<T, LANES>: AsRef<[T; LANES]>,
    T: SimdElement,
    LaneCount<LANES>: SupportedLaneCount,

is_sorted

nightly-only

检查此切片的元素是否已排序。

也就是说,对于每个元素 a 及其后续元素 ba <= b 必须成立。如果切片产生恰好产生零个或一个元素,则返回 true

请注意,如果 Self::Item 仅是 PartialOrd,而不是 Ord,则上述定义意味着,如果任何两个连续的项都不具有可比性,则此函数将返回 false

rust
pub fn is_sorted(&self) -> bool
where
    T: PartialOrd<T>,

返回值:返回bool值

rust
#![feature(is_sorted)]
let empty: [i32; 0] = [];

assert!([1, 2, 2, 9].is_sorted());
assert!(![1, 3, 2, 4].is_sorted());
assert!([0].is_sorted());
assert!(empty.is_sorted());
assert!(![0.0, 1.0, f32::NAN].is_sorted());

is_sorted_by

nightly-only

检查此切片的元素是否使用给定的比较器函数进行排序。

该函数使用给定的 compare 函数来确定两个元素的顺序,而不是使用 PartialOrd::partial_cmp。 除此之外,它等效于 is_sorted。有关更多信息,请参见其文档。

rust
pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where
    F: FnMut(&'a T, &'a T) -> Option<Ordering>,

参数

  • compare:指定的比较器函数

返回值:返回bool值

rust
#![feature(is_sorted)]

assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));

is_sorted_by_key

检查此切片的元素是否使用给定的键提取函数进行排序。

该函数将直接比较由 f 确定的元素的键,而不是直接比较切片的元素。 除此之外,它等效于 is_sorted。有关更多信息,请参见其文档。

rust
pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where
    F: FnMut(&'a T) -> K,
    K: PartialOrd<K>,

参数

  • f:谓词函数

返回值:返回bool值

rust
#![feature(is_sorted)]

assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));

partition_point

根据给定的谓词返回分区点的索引 (第二个分区的第一个元素的索引)。

假定切片根据给定的谓词进行了分区。 这意味着谓词返回 true 的所有元素都在切片的开头,谓词返回 false 的所有元素都在切片的结尾。

例如,[7, 15, 3, 5, 4, 12, 6] 在谓词 x % 2 != 0 下进行分区 (所有奇数都在开头,所有偶数都在结尾)。

如果未对该切片进行分区,则返回的结果是不确定的且无意义的,因为此方法执行一种二进制搜索。

另请参见 binary_searchbinary_search_bybinary_search_by_key

rust
pub fn partition_point<P>(&self, pred: P) -> usize
where
    P: FnMut(&T) -> bool,

参数

  • pred:谓词函数

返回值:返回bool值

rust
let v = [1, 2, 3, 3, 5, 6, 7];
let i = v.partition_point(|&x| x < 5);

assert_eq!(i, 4);
assert!(v[..i].iter().all(|&x| x < 5));
assert!(v[i..].iter().all(|&x| !(x < 5)));

如果切片的所有元素都与谓词匹配,包括切片是否为空,则将返回切片的长度:

rust
let a = [2, 4, 8];
assert_eq!(a.partition_point(|x| x < &100), a.len());
let a: [i32; 0] = [];
assert_eq!(a.partition_point(|x| x < &100), 0);

如果要在排序的 vector 中插入项目,同时保持排序顺序,请执行以下操作:

rust
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x < num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);

take

nightly-only

删除与给定范围对应的子切片,并返回对它的引用。

如果给定的范围越界,则返回 None 并且不修改切片。

请注意,此方法仅接受 2....6 等单侧范围,但不接受 2..6

rust
pub fn take<R, 'a>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where
    R: OneSidedRange<usize>,

参数

  • range:一个数组索引范围

返回值:返回一个Option,包含选取的范围内的元素组成的数组

rust
#![feature(slice_take)]

let mut slice: &[_] = &['a', 'b', 'c', 'd'];
let mut first_three = slice.take(..3).unwrap();

assert_eq!(slice, &['d']);
assert_eq!(first_three, &['a', 'b', 'c']);

获取切片的最后两个元素:

rust
#![feature(slice_take)]

let mut slice: &[_] = &['a', 'b', 'c', 'd'];
let mut tail = slice.take(2..).unwrap();

assert_eq!(slice, &['a', 'b']);
assert_eq!(tail, &['c', 'd']);

range 越界时会得到 None

rust
#![feature(slice_take)]

let mut slice: &[_] = &['a', 'b', 'c', 'd'];

assert_eq!(None, slice.take(5..));
assert_eq!(None, slice.take(..5));
assert_eq!(None, slice.take(..=4));
let expected: &[char] = &['a', 'b', 'c', 'd'];
assert_eq!(Some(expected), slice.take(..4));

take_mut

nightly-only

删除与给定范围对应的子切片,并返回对它的可变引用。

如果给定的范围越界,则返回 None 并且不修改切片。

请注意,此方法仅接受 2....6 等单侧范围,但不接受 2..6

rust
pub fn take_mut<R, 'a>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where
    R: OneSidedRange<usize>,

参数

  • range:一个数组索引范围

返回值:返回一个Option,包含选取的范围内的元素组成的数组的可变引用

获取切片的前三个元素:

rust
#![feature(slice_take)]

let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
let mut first_three = slice.take_mut(..3).unwrap();

assert_eq!(slice, &mut ['d']);
assert_eq!(first_three, &mut ['a', 'b', 'c']);

获取切片的最后两个元素:

rust
#![feature(slice_take)]

let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
let mut tail = slice.take_mut(2..).unwrap();

assert_eq!(slice, &mut ['a', 'b']);
assert_eq!(tail, &mut ['c', 'd']);

range 越界时会得到 None

rust
#![feature(slice_take)]

let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];

assert_eq!(None, slice.take_mut(5..));
assert_eq!(None, slice.take_mut(..5));
assert_eq!(None, slice.take_mut(..=4));
let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
assert_eq!(Some(expected), slice.take_mut(..4));

take_first

nightly-only

删除切片的第一个元素,并返回对它的引用。

如果切片为空,则返回 None

rust
pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

返回值:返回一个Option,包含切片中第一个元素的引用

rust
#![feature(slice_take)]

let mut slice: &[_] = &['a', 'b', 'c'];
let first = slice.take_first().unwrap();

assert_eq!(slice, &['b', 'c']);
assert_eq!(first, &'a');

take_first_mut

nightly-only

删除切片的第一个元素,并返回对它的可变引用。

如果切片为空,则返回 None

rust
pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

返回值:返回一个Option,包含切片中第一个元素的可变引用

rust
#![feature(slice_take)]

let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
let first = slice.take_first_mut().unwrap();
*first = 'd';

assert_eq!(slice, &['b', 'c']);
assert_eq!(first, &'d');

take_last

nightly-only

删除切片的最后一个元素,并返回对它的引用。

如果切片为空,则返回 None

rust
pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

返回值:返回一个Option,包含切片中最后一个元素的引用

rust
#![feature(slice_take)]

let mut slice: &[_] = &['a', 'b', 'c'];
let last = slice.take_last().unwrap();

assert_eq!(slice, &['a', 'b']);
assert_eq!(last, &'c');

take_last_mut

nightly-only

删除切片的最后一个元素,并返回对它的可变引用。

如果切片为空,则返回 None

rust
pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

返回值:返回一个Option,包含切片中最后一个元素的可变引用

rust
#![feature(slice_take)]

let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
let last = slice.take_last_mut().unwrap();
*last = 'd';

assert_eq!(slice, &['a', 'b']);
assert_eq!(last, &'d');

get_many_mut

nightly-only

在不进行边界检查的情况下,一次返回对多个索引的可变引用。

rust
pub unsafe fn get_many_unchecked_mut<const N: usize>(
    &mut self,
    indices: [usize; N]
) -> [&mut T; N]

参数

  • indices:一个由索引组成的数组

返回值:返回从索引数组中找到的数组元素组成的数组

rust
#![feature(get_many_mut)]

let v = &mut [1, 2, 3];
if let Ok([a, b]) = v.get_many_mut([0, 2]) {
    *a = 413;
    *b = 612;
}
assert_eq!(v, &[413, 2, 612]);

get_many_unchecked_mut

nightly-only

一次返回对多个索引的可变引用。

如果任何索引越界,或者同一索引被传递多次,则返回错误。

rust
pub unsafe fn get_many_unchecked_mut<const N: usize>(
    &mut self,
    indices: [usize; N]
) -> [&mut T; N]

参数

  • indices:一个由索引组成的数组

返回值:返回从索引数组中找到的数组元素组成的数组

rust
#![feature(get_many_mut)]

let v = &mut [1, 2, 3];
if let Ok([a, b]) = v.get_many_mut([0, 2]) {
    *a = 413;
    *b = 612;
}
assert_eq!(v, &[413, 2, 612]);

sort_floats

nightly-only

对浮点数切片进行排序。

这种排序是就地的 (即 不分配),O(n* log(n)) 最坏情况,并使用 f32::total_cmp 定义的排序。

rust
pub fn sort_floats(&mut self)

示例值

rust
#![feature(sort_floats)]
let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];

v.sort_floats();
let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];

assert_eq!(&v[..8], &sorted[..8]);
assert!(v[8].is_nan());

is_ascii

检查此切片中的所有字节是否都在 ASCII 范围内。

rust
pub fn is_ascii(&self) -> bool

返回值:返回bool值

as_ascii

nightly-only

如果此切片为 is_ascii,则将其作为 ASCII characters 的切片返回,否则返回 None

rust
pub fn as_ascii(&self) -> Option<&[AsciiChar]>

返回值:返回一个ASCII characters切片,包含在Option中

as_ascii_unchecked

nightly-only

将此字节片段转换为 ASCII 字符片段,而不检查它们是否有效。

rust
pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

TIP

切片中的每个字节都必须在 0..=127 中,否则就是 UB。

eq_ingore_ascii_case

检查两个片是否是 ASCII 大小写不敏感的匹配项。

to_ascii_lowercase(a) == to_ascii_lowercase(b) 相同,但不分配和复制临时文件。

rust
pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

make_ascii_uppercase

将该切片原位转换为其 ASCII 大写形式。

ASCII 字母 ‘a’ 到 ‘z’ 映射到 ‘A’ 到 ‘Z’,但是非 ASCII 字母不变。

要返回新的大写值而不修改现有值,请使用 to_ascii_uppercase

make_ascii_lowercase

将该切片原位转换为其 ASCII 小写等效项。

ASCII 字母 ‘A’ 到 ‘Z’ 映射到 ‘a’ 到 ‘z’,但是非 ASCII 字母不变。

要返回新的小写值而不修改现有值,请使用 to_ascii_lowercase

escape_ascii

返回一个迭代器,该迭代器产生此转义版本的一个 ASCII 字符串,将其视为一个 ASCII 字符串。

rust
pub fn escape_ascii(&self) -> EscapeAscii<'_>

返回值:返回一个EscapeAscii迭代器

rust
let s = b"0\t\r\n'\"\\\x9d";
let escaped = s.escape_ascii().to_string();
assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");

trim_ascii_start

nightly-only

返回删除了前导 ASCII 空白字节的字节切片。

‘Whitespace’ 是指 u8::is_ascii_whitespace 使用的定义。

rust
pub fn trim_ascii_start(&self) -> &[u8]

返回值:返回删除了前导 ASCII 空白字节的字节切片。

rust
#![feature(byte_slice_trim_ascii)]

assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
assert_eq!(b"  ".trim_ascii_start(), b"");
assert_eq!(b"".trim_ascii_start(), b"");

trim_ascii_end

nightly-only

返回删除了尾随 ASCII 空白字节的字节切片。

‘Whitespace’ 是指 u8::is_ascii_whitespace 使用的定义。

rust
pub fn trim_ascii_end(&self) -> &[u8]

返回值:返回删除了尾随 ASCII 空白字节的字节切片。

rust
#![feature(byte_slice_trim_ascii)]

assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
assert_eq!(b"  ".trim_ascii_end(), b"");
assert_eq!(b"".trim_ascii_end(), b"");

trim_ascii

nightly-only

返回删除了前导和尾随 ASCII 空白字节的字节切片。

‘Whitespace’ 是指 u8::is_ascii_whitespace 使用的定义。

rust
pub fn trim_ascii(&self) -> &[u8]

返回值:返回删除了前导和尾随 ASCII 空白字节的字节切片

rust
#![feature(byte_slice_trim_ascii)]

assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
assert_eq!(b"  ".trim_ascii(), b"");
assert_eq!(b"".trim_ascii(), b"");

as_str

nightly-only

将这片 ASCII 字符视为 UTF-8 str

rust
pub fn as_str(&self) -> &str

返回值:返回字符串切片

as_bytes

nightly-only

将此 ASCII 字符片段视为 u8 字节片段。

rust
pub fn as_bytes(&self) -> &[u8]

返回值:返回字节切片

to_ascii_uppercase

返回一个 vector,其中包含此切片的副本,其中每个字节都映射到其等效的 ASCII 大写字母。

ASCII 字母 ‘a’ 到 ‘z’ 映射到 ‘A’ 到 ‘Z’,但是非 ASCII 字母不变。

要就地将值大写,请使用 make_ascii_uppercase

rust
pub fn to_ascii_uppercase(&self) -> Vec<u8, Global>

返回值:返回一个 vector,其中包含此切片的副本,其中每个字节都映射到其等效的 ASCII 大写字母。

to_ascii_lowercase

返回一个 vector,其中包含该切片的副本,其中每个字节均映射为其等效的 ASCII 小写字母。

ASCII 字母 ‘A’ 到 ‘Z’ 映射到 ‘a’ 到 ‘z’,但是非 ASCII 字母不变。

要就地小写该值,请使用 make_ascii_lowercase

rust
pub fn to_ascii_lowercase(&self) -> Vec<u8, Global>

返回值:返回一个 vector,其中包含该切片的副本,其中每个字节均映射为其等效的 ASCII 小写字母。

sort

对切片进行排序。

这种排序是稳定的 (即,不对相等的元素重新排序),并且 O(n**log( n*)) 最坏的情况)。

在适用时,首选不稳定排序,因为它通常比稳定排序快,并且不分配辅助内存。 请参见 sort_unstable

rust
pub fn sort(&mut self)
where
    T: Ord,

示例

rust
let mut v = [-5, 4, 1, -3, 2];

v.sort();
assert!(v == [-5, -3, 1, 2, 4]);

TIP

当前的算法是一种受 timsort 启发的自适应迭代合并排序。 在切片几乎被排序或由两个或多个依次连接的排序序列组成的情况下,它设计得非常快。

同样,它分配临时存储空间的大小是 self 的一半,但是对于短片,则使用非分配插入排序。

sort_by

自定义比较函数 进行稳定排序

rust
pub fn sort_by<F>(&mut self, compare: F)
where
    F: FnMut(&T, &T) -> Ordering,

参数

  • compare:比较函数,返回Ordering,根据此函数的返回值进行排序
rust
fn main() {
    let mut v = [-5, 4, 1, -3, 2];

    v.sort_by(|a, b| b.cmp(a));

	println!("{:?}", v);  // [4, 2, 1, -3, -5]
}

多字段排序

rust
v.sort_by(|a, b| {
    a.age.cmp(&b.age)
        .then(b.score.cmp(&a.score))
});

sort_by_key

按某个 key 排序,比较逻辑自动生成

rust
pub fn sort_by_key<K, F>(&mut self, f: F)
where
    F: FnMut(&T) -> K,
    K: Ord,

参数

  • f:sort_by_key函数根据此函数返回的键进行排序
rust
#[derive(Debug)]
struct Person {
    name: &'static str,
    age: u8,
}

fn main() {
    let mut people = vec![
        Person { name: "Alice", age: 30 },
        Person { name: "Bob", age: 25 },
    ];

    people.sort_by_key(|p| p.age);
    println!("{:?}", people);
}

sort_by_cached_key

先把 key 算好缓存起来,再用这些 key 排序

rust
pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where
    F: FnMut(&T) -> K,
    K: Ord,

参数

  • f: key提取函数
rust
fn main() {
    let mut v = vec!["apple", "banana", "pear"];

    // 按字符串长度排序,长度只算一次
    v.sort_by_cached_key(|s| s.len());

    println!("{:?}", v);  // ["pear", "apple", "banana"]
}

具体字段排序

rust
#[derive(Debug)]
struct User {
    name: String,
}

fn main() {
    let mut users = vec![
        User { name: "alice".into() },
        User { name: "bob".into() },
        User { name: "charlie".into() },
    ];

    users.sort_by_cached_key(|u| u.name.len());

    println!("{:?}", users);  // [User { name: "bob" }, User { name: "alice" }, User { name: "charlie" }]
}

to_vec

self 复制到新的 Vec 中。

rust
pub fn to_vec(&self) -> Vec<T, Global>
where
    T: Clone,

返回值:返回复制完成后的Vec

rust
let s = [10, 40, 30];
let x = s.to_vec();
// 在此,`s` 和 `x` 可以独立修改。

to_vec_in

nightly-only

使用分配器将 self 复制到新的 Vec 中。

rust
pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where
    A: Allocator,
    T: Clone,

返回值:返回复制完成后的Vec

rust
#![feature(allocator_api)]

use std::alloc::System;

let s = [10, 40, 30];
let x = s.to_vec_in(System);
// 在此,`s` 和 `x` 可以独立修改。

repeat

通过复制切片 n 次创建 vector。

rust
pub fn repeat(&self, n: usize) -> Vec<T, Global>
where
    T: Copy,

参数

  • n:复制重复的次数

返回值:返回复制后创建的新Vec

rust
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);

溢出时为 panic:

rust
// 这将在运行时 panic
b"0123456789abcdef".repeat(usize::MAX);

concat

T 的切片展平为单个值 Self::Output

rust
pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where
    [T]: Concat<Item>,
    Item: ?Sized,

返回值:返回展平后的切片

rust
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);

join

T 的切片展平为单个值 Self::Output,并在每个值之间放置一个给定的分隔符。

rust
pub fn join<Separator>(
    &self,
    sep: Separator
) -> <[T] as Join<Separator>>::Output
where
    [T]: Join<Separator>,

参数

  • sep:分隔符

返回值:返回拼接后的新切片

rust
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);

connect

TIP

Deprecated since 1.3.0: renamed to join

T 的切片展平为单个值 Self::Output,并在每个值之间放置一个给定的分隔符。

rust
pub fn connect<Separator>(
    &self,
    sep: Separator
) -> <[T] as Join<Separator>>::Output
where
    [T]: Join<Separator>,

参数

  • sep:拼接符

返回值:返回拼接后的新切片

rust
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);

Trait Implementations

impl<'a> Debug for IoSliceMut<'a>

fmt

使用给定的格式化程序格式化该值。

rust
 fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

impl<'a> Deref for IoSliceMut<'a>

Target

解引用后的结果类型。

rust
type Target = [u8]

deref

解引用值。

rust
fn deref(&self) -> &[u8]

impl<'a> DerefMut for IoSliceMut<'a>

deref_mut

可变地解引用该值。

rust
fn deref_mut(&mut self) -> &mut [u8]

impl<'a> Send for IoSliceMut<'a>

impl<'a> Sync for IoSliceMut<'a>

Auto Trait Implementations

impl<'a> RefUnwindSafe for IoSliceMut<'a>

impl<'a> Unpin for IoSliceMut<'a>

impl<'a> UnwindSafe for IoSliceMut<'a>

Blanket Implementations

impl<T> Any for T

rust
impl<T> Any for T
where
    T: 'static + ?Sized,

impl<T> Borrow<T> for T

rust
impl<T> Borrow<T> for T
where
    T: ?Sized,

impl<T> BorrowMut<T> for T

rust
impl<T> BorrowMut<T> for T
where
    T: ?Sized,

impl<T> From<T> for T

impl<T, U> Into<U> for T

rust
impl<T, U> Into<U> for T
where
    U: From<T>,

impl<T, U> TryFrom<U> for T

rust
impl<T, U> TryFrom<U> for T
where
    U: Into<T>,

impl<T, U> TryInto<U> for T

rust
impl<T, U> TryInto<U> for T
where
    U: TryFrom<T>,

MIT Licensed