2311rust,到60版本更新
1.54.0
稳定版
属性可调用类似函数的宏
Rust1.54
支持在属性
中调用类似函数
的宏.类似函数的宏是像基于macro_rules!
宏一样调用的或像macro!(...)
一样的过程宏.
注意,常见用例是,在Rust
文档注解中包含其他文件中的文档
.如,如果项目的README
代表了一个很好的文档注释,则可用include_str!
直接整合
内容.
#![doc = include_str!("README.md")]
也可在属性中嵌套
宏.如,可用用stringify!
来包括替换的concat!
宏来构建
文档注释:
macro_rules! make_function {
($name:ident, $value:expr) => {
#[doc = concat!("The `", stringify!($name), "` example.")]
/// #示例
///```
#[doc = concat!(
"assert_eq!(", module_path!(), "::", stringify!($name), "(), ",
stringify!($value), ");")
]
///
pub fn $name() -> i32 {
$value
}
};
}
make_function! {func_name, 123}
更多.
稳定WASM32
内部函数
已稳定wasm32
平台的许多允许访问WebAssembly
中的SIMD
指令的内部函数
.
即可按完全安全
的函数公开
一些内部函数,如v128_bitselect
.但是,仍有一些内部函数
是不安全
的,因为它们使用原始指针,如v128_load
.
默认,重新启用增量编译
稳定的API
已稳定以下方法和特征实现
.
BTreeMap::into_keys
BTreeMap::into_values
HashMap::into_keys
HashMap::into_values
arch::wasm32
VecDeque::binary_search
VecDeque::binary_search_by
VecDeque::binary_search_by_key
VecDeque::partition_point
1.55.0
稳定版
Cargo
删除重复数据编译器错误
过去版本中,运行cargo test
,cargo check --all-targets
或类似的命令时,在多个配置
中构建了相同的Rust
仓库,因为是并行运行rustc
,可能会重复显示相同的错误和警告
.
如,在1.54.0
中,此输出很常见:
$ cargo +1.54.0 check --all-targets
Checking foo v0.1.0
warning: function is never used: `foo`
--> src/lib.rs:9:4
|
9 | fn foo() {}
| ^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted
warning: function is never used: `foo`
--> src/lib.rs:9:4
|
9 | fn foo() {}
| ^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.10s
在1.55
中,已调整为在编译结束
时删除重复数据
再打印报告:
$ cargo +1.55.0 check --all-targets
Checking foo v0.1.0
warning: function is never used: `foo`
--> src/lib.rs:9:4
|
9 | fn foo() {}
| ^^^
|
= note: `#[warn(dead_code)]` on by default
warning: `foo` (lib) generated 1 warning
warning: `foo` (lib test) generated 1 warning (1 duplicate)
Finished dev [unoptimized + debuginfo] target(s) in 0.84s
更快,更正确的浮点解析
已更新标准库的浮点解析
实现为提高速度和正确性
的Eisel-Lemire
算法,细节.
已更新std::io::ErrorKind
变体
std::io::ErrorKind
是一个可分类错误
为如NotFound
或WouldBlock
等可移植分类的#[non_exhaustive]
枚举.
有std::io::Error
的Rust
代码可调用kind
方法来取std::io::ErrorKind
,并匹配
该方法以处理指定错误.
并非所有错误
都归类为ErrorKind
值;在以前的Rust
版本中,未分类的错误
用ErrorKind::Other;
分类.
但是,用户创建的std::io::Error
值也常用ErrorKind::Other
.
在1.55
中,未分类的错误,现在使用内部变体ErrorKind::Uncategorized
,并打算隐藏它,且不能用稳定的Rust
代码命名;
这让ErrorKind::Other
专门构造非标准库的std::io::Error
值.这强制ErrorKind
的#[non_exhaustive]
本质.
Rust
代码永远不应与ErrorKind::Other
匹配,并期望特定的底层错误码
;仅当抓使用该错误类型
的已构造std::io::Error
时,才匹配ErrorKind::Other
.
匹配std::io::Error
的Rust
代码应总是用_
来表示未知错误类型
,此时,可匹配
底层错误码,或报告
错误,或冒泡
到调用代码.
此更改确保未知代码
匹配变体,必须使用既适合ErrorKind::Uncategorized
,也适合将来仅限nightly-only
的变体的_
抓所有模式.
添加了开区间模式
Rust1.55
稳定了模式
中使用
开区间:
match x as u32 {
0 => println!("zero!"),
1.. => println!("正数"),
}
细节.
稳定API
已稳定
以下方法和特征实现
.
Bound::cloned
Drain::as_str
IntoInnerError::into_error
IntoInnerError::into_parts
MaybeUninit::assume_init_mut
MaybeUninit::assume_init_ref
MaybeUninit::write
array::map
ops::ControlFlow
x86::_bittest
x86::_bittestandcomplement
x86::_bittestandreset
x86::_bittestandset
x86_64::_bittest64
x86_64::_bittestandcomplement64
x86_64::_bittestandreset64
x86_64::_bittestandset64
以下以前稳定的函数现在是常
.
str::from_utf8_unchecked
1.57.0
稳定版
在常环境中用恐慌!
以前版本Rust
,在const fn
和其他编译时环境中不可用恐慌!宏
.现在,已稳定下来.从而,其他几个标准库API
现在都可在常
中使用,比如assert!
.
现在必须用:
panic!("...")
//静态串
//或与{}搭配用的&str插值
panic!("{}", a)
该最小的稳定
已支持直接编译时
断定,如验证
类型的大小:
const _: () = assert!(std::mem::size_of::<u64>() == 8);
const _: () = assert!(std::mem::size_of::<u8>() == 1);
Cargo
自定义配置文件
Cargo
长期以来,一直支持四种配置文件
:dev,release,test
和bench
.在Rust1.57
中,支持任意命名
的配置文件
.
如,如果只想在最终生产版本
时,启用(LTO)
链接时优化,则在选择此配置文件
时,添加以下代码片
到Cargo.toml
会启用lto
标志,但避免普通发布
版本启用它.
[profile.production]
inherits = "release"
lto = true
注意,自定义
配置文件必须要继承的默认设置
的配置文件
.定义配置文件
后,构建时,可加上:
--profile production
目前,在单独的目录(在本例中为target/production
)中构建
,而不会在目录
间共享.
易错分配
Rust1.57
稳定了Vec,String,HashMap,HashSet
和VecDeque
的try_reserve
.
如果全局
分配器失败,Rust
一般会中止
进程,这并不总是可取的.此API
在使用标准库集合
时,可避免中止
.
但是,Rust
并不保证,由内核
分配返回内存
:如,如果在Linux
上启用了过提交(overcommit)
,则试使用
内存时,可能内存
不可用.
稳定的API
已稳定
以下方法和特征实现
.
[T; N]::as_mut_slice
[T; N]::as_slice
collections::TryReserveError
HashMap::try_reserve
HashSet::try_reserve
String::try_reserve
String::try_reserve_exact
Vec::try_reserve
Vec::try_reserve_exact
VecDeque::try_reserve
VecDeque::try_reserve_exact
Iterator::map_while
iter::MapWhile
proc_macro::is_available
Command::get_program
Command::get_args
Command::get_envs
Command::get_current_dir
CommandArgs
CommandEnvs
以前稳定
函数现在是常
.
hint::unreachable_unchecked
1.58.0
稳定版
格式串中抓标识
格式串
,现在只需在串
中写入{ident}
即可抓参数.长期以来格式
一直接受位置参数(可选按索引)和命名参数
,如:
println!("Hello, {}!", get_person()); //隐式位置
println!("Hello, {0}!", get_person()); //显式索引
println!("Hello, {person}!", person = get_person()); //命名
现在,还可从周围的域
抓命名参数
,如:
let person = get_person();
//...抓局部的"人"
println!("Hello, {person}!"); //
也可格式化
参数:
let (width, precision) = get_format();
for (name, score) in get_scores() {
println!("{name}: {score:width$.precision$}");
}
格式串
只能抓普通标识
,而不能抓任意路径或表达式
.对更复杂的参数
,请先它们给局部名
,或使用较旧的name=式
风格来设置参数格式
.
化简窗口
命令搜索路径
在窗口
目标上,std::process::Command
不再在当前目录
中搜索可执行文件.这是win32
的CreateProcessAPI
的遗留行为,因此Rust
按以下顺序
有效搜索:
(相关Rust
)子级的PATH
环境变量中列举
的目录(如果从父级显式更改该环境变量
).
1,从加载应用
的目录.
2,父进程
的当前目录.
3,32
位窗口
系统目录.
4,16
位窗口
系统目录.
5,窗口
目录.
6,在PATH
环境变量中列举
的目录.
窗口
上Rust
的新命令
搜索顺序为:
1,子级的PATH
环境变量中列举
的目录.
2,从加载应用
的目录.
3,32
位窗口
系统目录.
4,窗口
目录.
5,在PATH
环境变量中列举
的目录.
非窗口
目标继续使用其相关平台
行为,一般只考虑子或父PATH
环境变量.
标准库中更多#[must_use]
类型或函数
可应用#[must_use]
属性,如果不显式
考虑它们,输出
就会出错.在标准库中,长期以来一直用Result
等类型,应检查
它们是否存在错误条件
.
类似函数
的纯
,但比真正
的语言功能
更宽松.
稳定的API
Metadata::is_symlink
Path::is_symlink
{integer}::saturating_div
Option::unwrap_unchecked
Result::unwrap_unchecked
Result::unwrap_err_unchecked
File::options
常函数
Duration::new
Duration::checked_add
Duration::saturating_add
Duration::checked_sub
Duration::saturating_sub
Duration::checked_mul
Duration::saturating_mul
Duration::checked_div
1.58.1
稳定版
Rust1.58.1
修复了std::fs::remove_dir_all
标准库函数中的竞争.
修复了Rustfmt
中的通过标准输入
时阻止格式化
生成的文件.
修复了rustc
有时显示的错误信息
.
1.59.0
稳定版
内联汇编
Rust
语言现在支持内联汇编
.这样,可执行非常低级
的控制
,或访问专门的机器指令
.
如,针对x86-64
目标编译时,现在可编写:
use std::arch::asm;
//用`移位和加法`乘6
let mut x: u64 = 4;
unsafe {
asm!(
"mov {tmp}, {x}",
"shl {tmp}, 1",
"shl {x}, 2",
"add {x}, {tmp}",
x = inout(reg) x,
tmp = out(reg) _,
);
}
assert_eq!(x, 4 * 6);
在asm!
和global_asm!
宏中的格式串
语法与Rust
格式串中使用
的相同.
内联汇编
的汇编语言和指令
因目标架构
而异.目前,稳定的Rust
编译器支持以下架构
的内联汇编
:
x86 and x86-64
ARM
AArch64
RISC-V
更多
内联汇编见示例.
解构赋值
现在,可用元组,切片和结构模式
作为赋值左侧
.
let (a, b, c, d, e);
(a, b) = (1, 2);
[c, .., d, _] = [1, 2, 3, 4, 5];
Struct { e, .. } = Struct { e: 5, f: 3 };
assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]);
使得赋值
与let
绑定更加一致,注意,禁止使用(如+=
)符号解构赋值
.
常
泛型默认值和交错
泛型
类型,现在可为常量泛型
指定默认值.如,现在可编写
以下内容:
struct ArrayStorage<T, const N: usize = 2> {
arr: [T; N],
}
impl<T> ArrayStorage<T> {
fn new(a: T, b: T) -> ArrayStorage<T> {
ArrayStorage {
arr: [a, b],
}
}
}
以前,必须在所有常
参数前指定类型参数
.已放宽该限制
,现在可交错
.
fn cartesian_product<
T, const N: usize,
U, const M: usize,
V, F
>(a: [T; N], b: [U; M], f: F) -> [[V; N]; M]
where
F: FnMut(&T, &U) -> V
{
//...
}
创建去掉的二进制文件
从分发
的二进制文件中去掉不必要的信息
(如debuginfo
)来使它们变小,一般很有用.
虽然,创建
二进制文件后总是可手动
这样,但cargo
和rustc
现在支持在链接
二进制文件时去掉.要启用
此功能,在Cargo.toml
中加上:
[profile.release]
strip = "debuginfo"
更多细节
稳定的API
已稳定以下方法和特征实现
:
std::thread::available_parallelism
Result::copied
Result::cloned
arch::asm!
arch::global_asm!
ops::ControlFlow::is_break
ops::ControlFlow::is_continue
TryFrom<char> for u8
char::TryFromCharError implementing Clone, Debug, Display, PartialEq, Copy, Eq, Error
iter::zip
NonZeroU8::is_power_of_two
NonZeroU16::is_power_of_two
NonZeroU32::is_power_of_two
NonZeroU64::is_power_of_two
NonZeroU128::is_power_of_two
DoubleEndedIterator for ToLowercase
DoubleEndedIterator for ToUppercase
TryFrom<&mut [T]> for [T; N]
UnwindSafe for Once
RefUnwindSafe for Once
armv8 neon intrinsics for aarch64
以下稳定
函数现在是常
:
mem::MaybeUninit::as_ptr
mem::MaybeUninit::assume_init
mem::MaybeUninit::assume_init_ref
ffi::CStr::from_bytes_with_nul_unchecked