1.76.0
稳定版
此版本较小
ABI
兼容更新
函数指针
文档中新增的ABI
兼容部分介绍了函数签名
与ABI
兼容的意义.大部分是参数类型
和返回类型
的兼容,及在当前Rust
中兼容的列表
.文档仅描述现有兼容的状态.
一个新增
功能是,现在保证符
和u32
是ABI
兼容的.它们一直有相同大小
和对齐方式
,但现在即使在调用函数的ABI
中,与上面文档
一致,它们也是等价的.
引用中的类型名
为了调试,从Rust1.38
开始,就可用any::type_name::<T>()
返回T类型
的串描述
,但这需要一个显式的类型参数
.
指定该类型
会有点难,尤其是对无法命名的类型
(如闭包)或不透明的返回类型
.
新的any::type_name_of_val(&T)
可从类型引用
中取描述性名字
.
fn get_iter() -> impl Iterator<Item = i32> {[1, 2, 3].into_iter()
}
fn main() {let iter = get_iter();let iter_name = std::any::type_name_of_val(&iter);let sum: i32 = iter.sum();println!("The sum of the `{iter_name}` is {sum}.");
}
当前打印:
'core::array::iter::IntoIter<i32,3>'
的和是6
.
稳定的API
Arc::unwrap_or_clone
Rc::unwrap_or_clone
Result::inspect
Result::inspect_err
Option::inspect
type_name_of_val
ptr::{from_ref, from_mut}
ptr::addr_eq
std::hash::{DefaultHasher,RandomState}
这些以前只能通过std::collections::hash_map
取得.
1.77.0
稳定版
此版本较小
.
C串字面
Rust
现在支持在&'static CStr
内存类型中,扩展
到按nul
字节终止的串
的的C串字面
(c"abc"
).这样更易编写
与需要nul
结尾串的外部接口
互操作的代码,并在编译时
检查所有相关的错误
(如,缺少内部nul
字节).
支持异步fn
中的递归
因为编译器限制
,以前异步函数
无法调用自身
.在1.77
中,已取消该限制
,因此只要使用间接
以避免无穷大小
的函数状态
,就允许递归调用
.
即像此代码
现在可以工作
了:
async fn fib(n: u32) -> u32 {match n {0 | 1 => 1,_ => Box::pin(fib(n-1)).await + Box::pin(fib(n-2)).await}
}
offset_of!
对构字段
,1.77.0
稳定了可访问结构
的相关公
字段的字节偏移
的offset_of!
.当在没有类型的现成实例
,但需要字段的偏移
时,此宏
最有用.
用户
现在可用offset_of!(StructName, field)
访问公
字段的偏移
,它从结构开头开始
按字节用偏移扩展到usize
式.
默认,在发布配置文件中允许去掉
未在输出中允许调试信息
的cargo
配置文件(如,debug=0
)默认允许strip="debuginfo"
.
主要是因为(预编译的
)标准库
附带了调试信息
,即即使本地编译
没有显式
请求调试信息
,但静态链接
的结果包含
了标准库的调试信息
.
需要调试信息
的用户可用相关Cargo
配置文件中的调试
标志显式允许它
.
Stabilized APIs
array::each_ref
array::each_mut
core::net
f32::round_ties_even
f64::round_ties_even
mem::offset_of!
slice::first_chunk
slice::first_chunk_mut
slice::split_first_chunk
slice::split_first_chunk_mut
slice::last_chunk
slice::last_chunk_mut
slice::split_last_chunk
slice::split_last_chunk_mut
slice::chunk_by
slice::chunk_by_mut
Bound::map
File::create_new
Mutex::clear_poison
RwLock::clear_poison
1.78.0
稳定版
诊断属性
Rust
现在支持#[diagnostic]
属性名字空间
,来影响编译器错误消息
.按不要求编译器
用的提示
对待这些,提供编译器无法识别
的诊断
也不是错误.
该灵活性
使得即使并非所有
,无论是不同版本
还是完全不同实现
的编译器
,都支持它们
,源码
提供诊断.
此名字空间
带有第一个支持
的#[diagnostic::on_unimplemented]
属性,需要该特征
但尚未在类型
上实现时,可在特征
上放置
它以自定义消息
.
考虑稳定化拉请
中给出的示例
:
#[diagnostic::on_unimplemented(message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`",label = "My Label",note = "Note 1",note = "Note 2"
)]
trait ImportantTrait<A> {}
fn use_my_trait(_: impl ImportantTrait<i32>) {}
fn main() {use_my_trait(String::new());
}
以前,编译器会给出如下内置错误
:
错误[E0277]
:不满足'String:ImportantTrait<i32>'
的特征约束.
–>src/main.rs:12:18
|
12|use_my_trait(String::new());
|------------^^^^^^^^^^^^^未为'串'
实现'ImportantTrait<i32>'
特征
|此调用
引入的约束
的必需.
使用#[diagnostic::on_unimplemented]
,其自定义消息
填充主错误行
,在源输出
上放置其自定义标签
.仍按帮助输出
写入原标签
,且也会写入自定义注解
.
这些确切细节
可能会变化.
错误[E0277]
:未为'串'
实现'ImportantTrait<i32>'
的消息
–>src/main.rs:12:18
|
12|use_my_trait(String::new());
|------------^^^^^^^^^^^^^我的标签
|由此调用引入的约束
必需
=帮助
:未为'串'
实现'ImportantTrait<i32>'
特征
=注:注1
=注:注2
对特征
作者来说,如果可提供更好的提示
,而不仅是谈论
缺失的实现自身,则该诊断
会更有用
.如,这是标准
库中的删节示例
:
#[diagnostic::on_unimplemented(message = "the size for values of type `{Self}` cannot be known at compilation time",label = "doesn't have a size known at compiletime"
)]
pub trait Sized {}
断定不安全的前提条件
Rust
标准库有许多不安全
函数的前提条件
的断定,但历史上它们只在标准库
的#[cfg(debug_assertions)]
构建中允许,以避免影响发布性能
.
然而,因为一般是在发布模式
下编译和分发
的标准库
,因此大多数Rust
开发者并不检查这些
.
现在,延迟到生成代码
,才执行这些断定的条件
,因此根据用户自己的设置
来检查调试断定
,在调试和测试
构建中默认允许
.
尽管检查
的量的细节一般不稳定,此更改可帮助用户在其代码中抓未定义行为
.
如,slice::from_raw_parts
要求一个对齐
的非无效
指针.以下故意的未对齐指针
有未定义行为
,虽然如果你运气不佳
,在过去可能"有效
",但调试断定
现在可以抓住它
:
fn main() {let slice: &[u8] = &[1, 2, 3, 4, 5];let ptr = slice.as_ptr();//从对齐总是与`'u16'`的正确方式相差1个的`'针'`创建一个偏移let i = usize::from(ptr as usize & 1 == 0);let slice16: &[u16] = unsafe { std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 2) };dbg!(slice16);
}
在library/core/src/panicking.rs:220:5
处'main'
线程出现紧急情况
:
违反了不安全的前提条件
:slice::from_raw_parts
要求指针对齐
且非无效
,且切片的总大小
不超过'isize::MAX'
注意:使用'RUST_BACKTRACE=1'
环境变量运行以显示追踪追踪
线程
导致非展开崩溃
.中止.
确定性重新对齐
标准库有一些可改变指针
和切片
的对齐方式
的函数,但是如果严格遵守他们的文档
,它们以前有一些注意,这样,实际上难以依赖它们
.
这些警告
主要是为了对冲常
求值,但,它们只对非常
使用是稳定
的.现在,他们承诺根据其实际输入
,有一致的运行时行为
.
pointer::align_offset
计算,要按给定对齐
更改指针需要的偏移
.如果不行,它会返回usize::MAX
,但以前允许总是返回usize::MAX
,现在已删除该行为
.
slice::align_to
和slice::align_to_mut
都按对齐
的中间切片
和剩余的未对齐
的头
和尾切片
转换切片
.
这些方法
现在承诺返回尽量大的中间部分
,而不是允许实现返回次优
的,如按头片
返回所有内容
.
稳定的API
对多个std::error::Error
,接受相关实现
的非'static
生命期
impl Read for &Stdin
Makeimpl<Fd:AsFd>impltakeSized
implFrom<TryReserveError>forio::Error
这些API
现在在常
环境中是稳定的:
Barrier::new()
兼容说明
如前,Rust1.78
已要求其最低
提高到窗口10
,以实现以下目标
:
x86_64-pc-windows-msvc
i686-pc-windows-msvc
x86_64-pc-windows-gnu
i686-pc-windows-gnu
x86_64-pc-windows-gnullvm
i686-pc-windows-gnullvm
Rust1.78
的LLVM
已升级到18
版本,完成了已声明
的针对x86-32
和x86-64
目标的u128/i128ABI
更改.
1.79.0
稳定版
内联常
式
常{...}
块现在在式位置
上是稳定的,允许无需额外的声明
(如,在特征
上定义常
项或关联的常
)的,显式进入常
环境.
与常
项(const ITEM:...=...
)不同,内联常
可使用域内的泛型
,并推导其类型
而不是显式写出来
,这样,对内联代码片
特别有用.如,像此模式:
const EMPTY: Option<Vec<u8>> = None;
let foo = [EMPTY; 100];
//可写作:
let foo = [const { None }; 100];
注意,这也适合泛型环境
,以前要求带关联常
的冗长特征
声明:
fn create_none_array<T, const N: usize>() -> [Option<T>; N] {[const { None::<T> }; N]
}
这样,代码更加简洁并易于阅读
.
关联类型位置的约束
Rust1.79
稳定了关联项
的约束语法
,这允许在其他约束
内的关联类型位置
中放置约束
,即T:Trait<Assoc:Bounds...>
.
这样就不需要显式泛型类型
来约束关联类型
.
此功能允许在一些以前不可能
或要施加额外,不必要
的限制的地方,指定约束
:
where
子句,在此,相当于将约束
分割为两个(或多个)
,where
子句.
如,where T:Trait<Assoc:Bound>
等价于where T:Trait,<T as Trait>::Assoc:Bound
.
1,超级特征
,与where
子句不同,使用特征
时,通过新语法
隐式指定约束
.示例语法
:
trait CopyIterator: Iterator<Item: Copy> {}
2,关联类型项
约束,允许约束
与特征
的关联类型
关联的嵌套刚性投影
.如,
trait Trait { type Assoc: Trait2<Assoc2: Copy>; }
3,不透明类型约束
(RPIT,TAIT
),允许无需命名不透明类型
,约束与不透明类型
关联的关联类型
.如,impl Iterator<Item:Copy>
定义一个项
为复制
的迭代器
,不必实际将该项
叫约束
.
扩展自动临时生命期
现在在匹配
和如
构造中,自动扩展
在构造
中立即引用
的临时
的生命期.这与块结构
中扩展临时对象的生命期
一样.
如:
let a = if true {..;&temp() //过去错误,但现在扩展了生命期
} else {..;&temp() //过去错误,但现在扩展了生命期
};
//而
let a = match () {_ => {..;&temp() //过去错误,但现在扩展了生命期}
};
现在与之前行为
一致:
let a = {..;&temp() //扩展生命期
};
因为这些程序过去编译失败
,此行为后向兼容
.
在标准库构建中允许帧指针
标准库
现在使用-Cforce-frame-pointers=yes
编译分发Rust
项,使下游用户可更轻松地分析他们的程序
.注意,尽管在Cargo
的发布配置文件
中默认去掉它
,标准库还继续提供了行级调试信息
(如,DWARF
).
稳定的API
{integer}::unchecked_add
{integer}::unchecked_mul
{integer}::unchecked_sub
<[T]>::split_at_unchecked
<[T]>::split_at_mut_unchecked
<[u8]>::utf8_chunks
str::Utf8Chunks
str::Utf8Chunk
<*const T>::is_aligned
<*mut T>::is_aligned
NonNull::is_aligned
<*const [T]>::len
<*mut [T]>::len
<*const [T]>::is_empty
<*mut [T]>::is_empty
NonNull::<[T]>::is_empty
CStr::count_bytes
io::Error::downcast
num::NonZero<T>
path::absolute
proc_macro::Literal::byte_character
proc_macro::Literal::c_string
这些API
现在在常
环境中是稳定
的:
Atomic*::into_inner
io::Cursor::new
io::Cursor::get_ref
io::Cursor::position
io::empty
io::repeat
io::sink
panic::Location::caller
panic::Location::file
panic::Location::line
panic::Location::column