• 2311rust,到38版本更新


    1.35.0稳定版

    此版本亮点是分别为Box,BoxBox实现了FnOnce,FnMutFn闭包特征.
    此外,现在可按不安全的函数指针转换闭包.现在也可无参调用dbg!.

    Box实现Fn*装饰特征.

    以前,如果要调用在盒子闭包中存储的函数,因为Box等实例没有实现相应的Fn*特征,则必须使用FnBox.

    此版本中,可使用盒子函数.
    以下代码现在可工作了:

    fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> {
        vec![1, 2, 3, 4].into_iter().map(x).collect()
    }
    
    • 1
    • 2
    • 3

    此外,现在可直接调用Box对象:

    fn foo(x: Box<dyn FnOnce()>) {
        x()
    }
    
    • 1
    • 2
    • 3

    强制闭包为不安全的fn指针

    Rust1.19.0开始,可把未从环境中抓的闭包转换为函数指针.如,可编写:

    fn twice(x: u8, f: fn(u8) -> u8) -> u8 {
        f(f(x))
    }
    fn main() {
        assert_eq!(42, twice(0, |x| x + 21));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    但是,并未扩展到不安全函数指针.有了该版本Rust,现在可以这样做了.如:

    //安全不变量是传递的"`不安全 fn"`指针的不变量.
    unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) {
        f()
    }
    fn main() {
        //安全性:没有不变量.装饰静态禁止不安全.
        unsafe {
            call_unsafe_fn_ptr(|| {
                dbg!();
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    无参调用dbg!()

    该宏允许用环境快速检查某些式的值.如,运行时:

    fn main() {
        let mut x = 0;
        if dbg!(x == 1) {
            x += 1;
        }
        dbg!(x);
    }
    ...会看见:
    [src/main.rs:4] x == 1 = false
    [src/main.rs:8] x = 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如上,调用call_unsafe_fn_ptr高级函数,现在也可不传递参数调用dbg!.在跟踪应用选取分支时非常有用.如,用:

    fn main() {
        let condition = true;
        if condition {
            dbg!();
        }
    }
     ...你会看到:
    [src/main.rs:5]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    稳定库

    复制浮点数A符号到B符号上
    本版本中,已添加copysign新方法到f32f64浮点原语类型中:

    f32::copysign
    f64::copysign
    
    • 1
    • 2

    即,可用它复制A数字符号B数字上.如:

    fn main() {
        assert_eq!(3.5_f32.copysign(-0.42), -3.5);
    }
    
    • 1
    • 2
    • 3

    检查Range是否包含值

    Rust1.35.0Range类型上包含了一些新创建方法:

    Range::contains
    RangeFrom::contains
    RangeTo::contains
    RangeInclusive::contains
    RangeToInclusive::contains
    
    • 1
    • 2
    • 3
    • 4
    • 5

    现在,可轻松检查给定值是否在某个内.如,可编写:

    fn main() {
        if (0..=10).contains(&5) {
            println!("Five is included in zero to ten.");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    把借用的RefCell值映射并拆分为两部分

    现在可为借入数据的不同组件,映射并拆分多个借用值,来借用RefCell值:

    Ref::map_split
    RefMut::map_split
    
    • 1
    • 2

    通过闭包替换RefCell的值

    RefCellreplace_with方便方法:

    RefCell::replace_with
    
    • 1

    有了它,可舒适映射和替换单元格的当前值,并因取回旧值.

    按地址(而不是值)哈希处理指针或引用

    引入了:

    ptr::hash
    
    • 1

    此函数原始指针并哈希处理它.使用ptr::hash,可避免哈希引用值,而是哈希地址.

    复制Option<&T>的内容

    Rust1.0.0开始,Option<&T>Option::cloned方法和Option<&mutT>就允许你在Some(_)时克隆内容.
    然而,克隆有时很贵,而opt.cloned()方法没有提供提示.
    在该版本的Rust中:
    Option<&T>Option<&mut;T>,引入了Option::copied.
    opt.copied()的功能与opt.cloned()的功能相同.但是,调用该方法需要T:Copy.使用此方法,可确保在T不再实现Copy时,代码停止编译.

    更改Clippy

    Clippy添加了一个新的drop_bounds检查.把绑定的T:Drop添加到泛型函数时,会触发此检查.如:

    fn foo<T: Drop>(x: T) {}
    
    • 1

    绑定T:Drop几乎总是个错误,因为它排除了有很简单胶水的u8等类型.此外,T:Drop并没有直接考虑像String类没有有趣析构器行为的类型,而是按嵌入类型(如Vec)等有有趣析构器行为.

    除了drop_bounds之外,此版本的Clippy还将lintredundant_closure拆分为redundant_closureredundant_closure_for_method_calls.

    1.36.0稳定版

    Rust1.36.0中,稳定了Future!

    稳定了未来,给重要的crate,库和生态系统时间来准备async/.await.
    alloc是稳定的
    1.36.0之前,标准库由std,coreproc_macro仓库组成.核心仓库提供了IteratorCopy等核心功能,也可在#![no_std]环境中用,因为它没有强加要求.

    同时,std仓库提供了BoxOS功能等类型,但要求全局分配器和其他OS功能为基础.

    Rust1.36.0开始,依赖全局分配器的std部分,如Vec,现在可在alloc仓库中使用.
    然后,标准仓库会重新导出这些部件.虽然#![no_std]使用alloc的二进制文件仍需要每晚的Rust,#![no_std]库可在稳定的Rust中使用alloc仓库.

    同时,普通没有#![no_std]二进制文件,可依赖此仓库.来支持用alloc支持#![no_std].

    #![no_std]
    extern crate alloc;
    use alloc::vec::Vec;
    
    • 1
    • 2
    • 3

    MaybeUninit而不是mem::uninitialized

    已稳定下来MaybeUninit类型.它不应假设MaybeUninit是正确初化的T.

    因此,可更安全渐进式初化,并在确定maybe_t:MaybeUninit包含初化的T后最终使用.assume_init().

    因为MaybeUninit更安全,将弃用mem::uninitialized函数.

    Rust2015NLL

    如,你现在可编写:

    fn main() {
        let mut x = 5;
        let y = &x;
        let z = &mut x; //在`1.31.0`之前禁止这样做.
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    新的HashMap实现

    基于SwissTable设计的hashbrown中的实现已取代HashMap的实现.虽然接口相同,但HashMap实现,现在平均速度更快,内存成本更低.

    新的Cargo标志已稳定:--offline.

    更改库

    dbg!宏现在支持多个参数.
    此外,多个API变成:

    Layout::from_size_align_unchecked
    mem::needs_drop
    NonNull::dangling
    NonNull::cast
    
    • 1
    • 2
    • 3
    • 4

    新的API已稳定,包括:
    1,task::Wakertask::Poll
    2,VecDeque::rotate_leftVecDeque::rotate_right
    3,Read::read_vectoredWrite::write_vectored
    4,Iterator::copied
    5,串的BorrowMut
    6,str::as_mut_ptr

    1.37.0稳定版

    通过类型别名引用枚举变体

    现在可用类型别名引用枚举变体.如:

    type ByteOption = Option<u8>;
    fn increment_or_zero(x: ByteOption) -> u8 {
        match x {
            ByteOption::Some(y) => y + 1,
            ByteOption::None => 0,
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实现中,Self行为类似类型别名.因此,现在也可用Self::Variant引用枚举变体:

    impl Coin {
        fn value_in_cents(&self) -> u8 {
            match self {
                Self::Penny => 1,
                Self::Nickel => 5,
                Self::Dime => 10,
                Self::Quarter => 25,
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Rust现在允许通过"类型相关解析来引用枚举变体.

    对宏使用未命名的const

    现在,可用_创建无名常量项.如,在rustc编译器中,发现:

    ///类型大小断定,第一个参数是类型,第二个参数是期望大小.
    #[macro_export]
    macro_rules! static_assert_size {
        ($ty:ty, $size:expr) => {
            const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
            //注意此处的下划线.
        }
    }
    static_assert_size!(Option<Box<String>>, 8); //1.
    static_assert_size!(usize, 8); //2.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注意第二个static_assert_size!(..):因为使用了无名常量,可在无名字冲突时,定义新项目.

    按配置文件优化

    rustc编译器现在通过-C profile-generate-C profile-use标志支持按配置文件优化(PGO).
    PGO允许编译器根据实际工作负载优化代码.工作原理是编译器分两步优化:
    1,首先,通过传递-C profile-generate标志给rustc来,用编译器插入的检测来构建程序.
    然后,对示例数据运行检测程序,并写入配置文件.
    2,然后,再次构建程序,这次使用-Cprofile-use标志收集的分析数据喂给rustc.使编译器更好放置代码,内联和其他优化.

    [package]部分中声明键时,如果未传递--bin标志,cargo run默认为选二进制文件.

    在枚举上#[repr(align(N))]]

    #[repr(align(N))]属性可用来提高类型定义的对齐方式.以前,只允许在结构和联上使用该属性.现在也可在枚举中定义.

    如,Align16类型期望按16位对齐,而没有#[repr(align(16))]自然对齐方式将为4:

    #[repr(align(16))]
    enum Align16 {
        Foo { foo: u32 },
        Bar { bar: u32 },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在枚举上使用#[repr(align(N))的语义与定义有该对齐的包装结构AlignN然后使用AlignN语义相同:

    #[repr(align(N))]
    struct AlignN<T>(T);
    
    • 1
    • 2

    更改库

    稳定了许多标准库:

    BufReader::buffer和BufWriter::buffer
    Cell::from_mut
    Cell::as_slice_of_cells
    DoubleEndedIterator::nth_back
    Option::xor
    {i,u}{8,16,32,64,128,size}::reverse_bits and Wrapping::reverse_bits
    slice::copy_within
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    使用boost::serialization模块实现快速进制归档的测试程序
    蓝桥杯实战应用【算法代码篇】-希尔排序(附python、Java、C++和C语言代码)
    java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    Windows实时运动控制软核(一):LOCAL高速接口测试之C#
    飞天使-template模版相关知识
    Kaggle Feedback Prize 3比赛总结:如何高效使用hidden states输出(1)
    【k8s】(五)kubernetes1.29.4离线部署之-初始化第一个控制平面
    少儿编程 电子学会图形化 scratch编程等级考试四级真题答案解析(判断题)2022年9月
    2022.11.20 学习周报
    机器学习 —— 简单模型的构建
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/134472669