1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
//! 从字节切片创建 `str` 的方法。
use crate::mem;
use super::validations::run_utf8_validation;
use super::Utf8Error;
/// 将字节切片转换为字符串切片。
///
/// 字符串 ([`&str`]) 由字节 ([`u8`]) 组成,字节 ([`&[u8]`][byteslice]) 由字节组成,因此此函数在两者之间进行转换。
/// 并非所有的字节片都是有效的字符串切片,但是: [`&str`] 要求它是有效的 UTF-8。
/// `from_utf8()` 检查以确保字节是有效的 UTF-8,然后进行转换。
///
/// [`&str`]: str
/// [byteslice]: slice
///
/// 如果您确定字节切片是有效的 UTF-8,并且不想增加有效性检查的开销,则此函数有一个不安全的版本 [`from_utf8_unchecked`],它具有相同的行为,但是会跳过检查。
///
///
/// 如果需要 `String` 而不是 `&str`,请考虑使用 [`String::from_utf8`][string]。
///
/// [string]: ../../std/string/struct.String.html#method.from_utf8
///
/// 因为您可以栈分配 `[u8; N]`,也可以使用它的 [`&[u8]`][byteslice],所以此函数是具有栈分配的字符串的一种方法。在下面的示例部分中有一个示例。
///
/// [byteslice]: slice
///
/// # Errors
///
/// 如果切片不是 UTF-8,则返回 `Err`,并说明为什么提供的切片不是 UTF-8。
///
/// # Examples
///
/// 基本用法:
///
/// ```
/// use std::str;
///
/// // vector 中的一些字节
/// let sparkle_heart = vec![240, 159, 146, 150];
///
/// // 我们知道这些字节是有效的,因此只需使用 `unwrap()`。
/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap();
///
/// assert_eq!("💖", sparkle_heart);
/// ```
///
/// 字节不正确:
///
/// ```
/// use std::str;
///
/// // vector 中的一些无效字节
/// let sparkle_heart = vec![0, 159, 146, 150];
///
/// assert!(str::from_utf8(&sparkle_heart).is_err());
/// ```
///
/// 有关可以返回的错误类型的更多详细信息,请参见 [`Utf8Error`] 文档。
///
/// 一个栈分配的字符串:
///
/// ```
/// use std::str;
///
/// // 栈分配的数组中的一些字节
/// let sparkle_heart = [240, 159, 146, 150];
///
/// // 我们知道这些字节是有效的,因此只需使用 `unwrap()`。
/// let sparkle_heart: &str = str::from_utf8(&sparkle_heart).unwrap();
///
/// assert_eq!("💖", sparkle_heart);
/// ```
///
///
///
///
///
///
///
///
///
///
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_str_from_utf8_shared", since = "1.63.0")]
#[rustc_allow_const_fn_unstable(str_internals)]
pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
// FIXME: 这应该再次使用 `?`,一旦它是 `const`
match run_utf8_validation(v) {
Ok(_) => {
// SAFETY: 验证成功。
Ok(unsafe { from_utf8_unchecked(v) })
}
Err(err) => Err(err),
}
}
/// 将字节的可变切片转换为可变字符串切片。
///
/// # Examples
///
/// 基本用法:
///
/// ```
/// use std::str;
///
/// // "Hello, Rust!" 作为一个附属 vector
/// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33];
///
/// // 我们知道这些字节是有效的,因此我们可以使用 `unwrap()`
/// let outstr = str::from_utf8_mut(&mut hellorust).unwrap();
///
/// assert_eq!("Hello, Rust!", outstr);
/// ```
///
/// 字节不正确:
///
/// ```
/// use std::str;
///
/// // 可变 vector 中的一些无效字节
/// let mut invalid = vec![128, 223];
///
/// assert!(str::from_utf8_mut(&mut invalid).is_err());
/// ```
/// 有关可以返回的错误类型的更多详细信息,请参见 [`Utf8Error`] 文档。
///
#[stable(feature = "str_mut_extras", since = "1.20.0")]
#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")]
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
// 这应该再次使用 `?`,一旦它是 `const`
match run_utf8_validation(v) {
Ok(_) => {
// SAFETY: 验证成功。
Ok(unsafe { from_utf8_unchecked_mut(v) })
}
Err(err) => Err(err),
}
}
/// 将字节切片转换为字符串切片,而无需检查字符串是否包含有效的 UTF-8。
///
///
/// 有关更多信息,请参见安全版本 [`from_utf8`]。
///
/// # Safety
///
/// 传入的字节必须是有效的 UTF-8。
///
/// # Examples
///
/// 基本用法:
///
/// ```
/// use std::str;
///
/// // vector 中的一些字节
/// let sparkle_heart = vec![240, 159, 146, 150];
///
/// let sparkle_heart = unsafe {
/// str::from_utf8_unchecked(&sparkle_heart)
/// };
///
/// assert_eq!("💖", sparkle_heart);
/// ```
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
// SAFETY: 调用者必须保证字节 `v` 是有效的 UTF-8。
// 还依赖于 `&str` 和 `&[u8]` 具有相同的布局。
unsafe { mem::transmute(v) }
}
/// 将字节切片转换为字符串切片,而无需检查字符串是否包含有效的 UTF-8; 可变版本。
///
///
/// 有关更多信息,请参见不可变版本 [`from_utf8_unchecked()`]。
///
/// # Examples
///
/// 基本用法:
///
/// ```
/// use std::str;
///
/// let mut heart = vec![240, 159, 146, 150];
/// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) };
///
/// assert_eq!("💖", heart);
/// ```
#[inline]
#[must_use]
#[stable(feature = "str_mut_extras", since = "1.20.0")]
#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked_mut", issue = "91005")]
pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
// SAFETY: 调用者必须保证字节 `v` 是有效的 UTF-8,因此将其强制转换为 `*mut str` 是安全的。
// 而且,指针解引用是安全的,因为该指针来自引用,保证对写有效。
//
//
unsafe { &mut *(v as *mut [u8] as *mut str) }
}