1.50.0
稳定版
常量泛型数组索引
继续
向稳定
的常量泛型
迈进,此版本为[T;N]
数组,添加了ops::Index和IndexMut
的实现.
cpp
fn second<C>(container: &C) -> &C::Output
where
C: std::ops::Index<usize> + ?Sized,
{
&container[1]
}
fn main() {
let array: [i32; 3] = [1, 2, 3];
assert_eq!(second(&array[..]), &2); //切片以前工作,
assert_eq!(second(&array), &2); //现在也可直接工作
}
数组的常量值重复
可按[a,b,c]
列表或[x;N]
重写Rust
中的数组.对N>1
,只允许对带Copy
的x
重复,且允许
在那里使用const
式.
自Rust1.38
以来,实现意外
地允许在数组
重复中稳定
地使用const
值.
cpp
fn main() {
//禁止的,因为`'Option<Vec<i32>>'`没有实现`'Copy'`.
let array: [Option<Vec<i32>>; 10] = [None; 10];
const NONE: Option<Vec<i32>> = None;
const EMPTY: Option<Vec<i32>> = Some(Vec::new());
//但是,允许重复`"const"`值!
let nones = [NONE; 10];
let empties = [EMPTY; 10];
}
在Rust1.50
中,正式承认了该稳定性
.
安全分配ManuallyDrop<T>
联字段
在赋值
字段时,联
不会删除旧值
,因此Rust
以前将其限制为仅从不析构(Drop)
的复制类型
.当然,ManuallyDrop<T>
也不需要Drop
,所以现在Rust1.50
允许安全地给这些字段赋值
.
Unix
平台上文件的利基市场
在Rust1.28
中,引入了非零整数
类型(如NonZeroU8
),其中0
是利基,允许Option<NonZero>
不用额外内存
用0
表示None
.
在Unix
平台上,Rust
的文件
只是由系统的整数文件描述符
组成,这里它永远不可能是-1
!
返回文件描述符
的系统
调用,使用-1
来指示错误(checkerrno)
,因此-1
不可能是真正
的文件描述符.
从Rust1.50
开始,可用它来优化布局
.因此,Option<File>
现在大小与File
自身相同!
更改库
在Rust1.50.0
中,有9个新的稳定函数
:
cpp
bool::then
btree_map::Entry::or_insert_with_key
f32::clamp
f64::clamp
hash_map::Entry::or_insert_with_key
Ord::clamp
RefCell::take
slice::fill
UnsafeCell::get_mut
且大量现有函数
是常量
:
cpp
IpAddr::is_ipv4
IpAddr::is_ipv6
Layout::size
Layout::align
Layout::from_size_align
所有整数类型的PoW.
1,对整,checked_pow
.
2,对整,saturating_pow
.
3,对整,wrapping_pow
.
4,对正,next_power_of_two
.
5,对正,checked_power_of_two
.
1.51.0
稳定版
Const
泛型MVP
此版本之前,Rust
允许你在生命期或类型
中参数化类型
.如,如果想要有个通用结构数组
,可编写
以下内容:
cpp
struct FixedArray<T> {
//^^^定义
list: [T; 32]
//^使用.
}
随后使用FixedArray<u8>
,编译器生成FixedArray
的单态
版本,如下:
cpp
struct FixedArray<u8> {
list: [u8; 32]
}
在数组
中最为明显,有了1.51.0
,你可编写对整数,布尔值或符类型的值
的泛型
代码!(使用struct
或enum
值仍不稳定).
看看定义,及用法.
cpp
struct Array<T, const LENGTH: usize> {
//^^^^^^^^^^^^^^^^^^^常泛型定义.
list: [T; LENGTH]
//^^^^^^在此使用它.
}
现在,如果使用Array<u8,32>
,编译器生成Array
的单态
版本,如下:
cpp
struct Array<u8, 32> {
list: [u8; 32]
}
稳定array::IntoIter
作为常
泛型稳定的一部分,还在稳定使用它的新API
,即std::array::IntoIter
.IntoIter
允许在数组
上创建按值
迭代器.
以前,不方便遍历
数组的拥有
值,只能引用
它们.
cpp
fn main() {
let array = [1, 2, 3, 4, 5];
//以前
for item in array.iter().copied() {
println!("{}", item);
}
//现在
for item in std::array::IntoIter::new(array) {
println!("{}", item);
}
}
注意,这是按独立
方法添加的,而不是数组
上的.into_iter()
,因为这会引入
一定程度的破坏;目前.into_iter()
是指切片引用
迭代器.
Cargo
的新功能解析器
Cargo.toml
中有个新的解析器选项
,可在其中设置resolver="2"
来告诉cargo
试一个新的方法来解析功能.
有开发,主机,目标
依赖项,细节
cpp
[package]
resolver = "2"
//或工作区.
[workspace]
resolver = "2"
拆分调试信息
cpp
[profile.dev]
split-debuginfo = "unpacked"
稳定api
总之,该版本稳定了18
种新方法,适合各种类型,如slice
和Peekable
.注意ptr::addr_of!
和ptr::addr_of_mut!
的稳定性
,它允许你创建指向未对齐字段
的原始指针
.
这两个宏
允许安全创建未对齐的指针
.
cpp
use std::ptr;
#[repr(packed)]
struct Packed {
f1: u8,
f2: u16,
}
let packed = Packed { f1: 1, f2: 2 };
//`'&packed.f2'`创建未对齐的引用,因此是未定义行为!
let raw_f2 = ptr::addr_of!(packed.f2);
assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
以下方法已稳定.
cpp
Arc::decrement_strong_count
Arc::increment_strong_count
Once::call_once_force
Peekable::next_if_eq
Peekable::next_if
Seek::stream_position
array::IntoIter
panic::panic_any
ptr::addr_of!
ptr::addr_of_mut!
slice::fill_with
slice::split_inclusive_mut
slice::split_inclusive
slice::strip_prefix
slice::strip_suffix
str::split_inclusive
sync::OnceState
task::Wake
1.52.0
稳定版
以前,先运行cargo check
,然后运行cargo clippy
不会运行Clippy
:Cargo
中的构建缓存
不会区分两者.但是,在1.52
中,已修复此问题
.
已稳定以下方法
.
cpp
Arguments::as_str
char::MAX
char::REPLACEMENT_CHARACTER
char::UNICODE_VERSION
char::decode_utf16
char::from_digit
char::from_u32_unchecked
char::from_u32
slice::partition_point
str::rsplit_once
str::split_once
以前稳定
的API
现在是常
.
cpp
char::len_utf8
char::len_utf16
char::to_ascii_uppercase
char::to_ascii_lowercase
char::eq_ignore_ascii_case
u8::to_ascii_uppercase
u8::to_ascii_lowercase
u8::eq_ignore_ascii_case
1.53.0
稳定版
数组的IntoIterator
这是数组实现IntoIterator
特征的第一个Rust
版本.现在可按值
遍历数组:
cpp
for i in [1, 2, 3] {
..
}
以前,只能用&[1,2,3]
或[1,2,3].iter()
引用来实现.
同样,你现在可把数组
传递给需要T:IntoIterator
的方法:
cpp
let set = BTreeSet::from_iter([1, 2, 3]);
for (a, b) in some_iterator.chain([1]).zip([1, 2, 3]) {
..
}
或模式
模式
语法已在任意位置支持嵌套|
.这样可编写Some(1|2)
而不是Some(1) | Some(2)
.
cpp
match result {
Ok(Some(1 | 2)) => { .. }
Err(MyError { kind: FileNotFound | PermissionDenied, .. }) => { .. }
_ => { .. }
}
Unicode
标识
标识现在可包含非ASCII
符.现在可用UAX#31
中定义的Unicode
中的所有有效标识
.包括许多不同脚本和语言
的角色,但不包括表情符号
.
如:
cpp
const BL HAJ: &str = " ";
struct 人 {
名字: String,
}
let α = 1;
Cargo
中的HEAD
分支名支持
Cargo
不再假定git
仓库的默认HEAD
名为master
.
已稳定以下方法和特征实现
.
cpp
array::from_ref
array::from_mut
AtomicBool::fetch_update
AtomicPtr::fetch_update
BTreeSet::retain
BTreeMap::retain
BufReader::seek_relative
cmp::min_by
cmp::min_by_key
cmp::max_by
cmp::max_by_key
DebugStruct::finish_non_exhaustive
Duration::ZERO
Duration::MAX
Duration::is_zero
Duration::saturating_add
Duration::saturating_sub
Duration::saturating_mul
f32::is_subnormal
f64::is_subnormal
IntoIterator for array
{integer}::BITS
io::Error::Unsupported
NonZero*::leading_zeros
NonZero*::trailing_zeros
Option::insert
Ordering::is_eq
Ordering::is_ne
Ordering::is_lt
Ordering::is_gt
Ordering::is_le
Ordering::is_ge
OsStr::make_ascii_lowercase
OsStr::make_ascii_uppercase
OsStr::to_ascii_lowercase
OsStr::to_ascii_uppercase
OsStr::is_ascii
OsStr::eq_ignore_ascii_case
Peekable::peek_mut
Rc::increment_strong_count
Rc::decrement_strong_count
slice::IterMut::as_slice
AsRef<[T]> for slice::IterMut
impl SliceIndex for (Bound<usize>, Bound<usize>)
Vec::extend_from_within