• 2311rust,到35版本更新


    1.32.0

    rustup self update
    rustup update stable
    
    • 1
    • 2

    rustup更新自己.

    dbg

    打印调试,你需要:

    let x = 5;
    println!("{:?}", x);
    //甚至可能是
    println!("{:#?}", x);
    
    • 1
    • 2
    • 3
    • 4

    Rust1.32.0中,为此添加了个新的dbg!宏:

    fn main() {
        let x = 5;
        dbg!(x);
    }
    
    • 1
    • 2
    • 3
    • 4

    如果运行此程序,会看到:

    [src/main.rs:4] x = 5
    
    • 1

    你获得了调用此文件的文件和行号,及名字和值.此外,println!打印到标准输出,所以要用eprintln!打印到标准错误.dbg!干活,然后在stderr输出.
    看看阶乘示例:

    fn factorial(n: u32) -> u32 {
        if n <= 1 {
            n
        } else {
            n * factorial(n - 1)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果想调试它,可用eprintln这样:

    fn factorial(n: u32) -> u32 {
        eprintln!("n: {}", n);
        if n <= 1 {
            eprintln!("n <= 1");
            n
        } else {
            let n = n * factorial(n - 1);
            eprintln!("n: {}", n);
            n
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    想在每次迭代时记录n,并为每个分支提供某种环境.查看factorial(4)的输出:

    n: 4
    n: 3
    n: 2
    n: 1
    n <= 1
    n: 2
    n: 6
    n: 24
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用dbg!

    fn factorial(n: u32) -> u32 {
        if dbg!(n <= 1) {
            dbg!(1)
        } else {
            dbg!(n * factorial(n - 1))
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    得到的输出:

    [src/main.rs:3] n <= 1 = false
    [src/main.rs:3] n <= 1 = false
    [src/main.rs:3] n <= 1 = false
    [src/main.rs:3] n <= 1 = true
    [src/main.rs:4] 1 = 1
    [src/main.rs:5] n * factorial(n - 1) = 2
    [src/main.rs:5] n * factorial(n - 1) = 6
    [src/main.rs:5] n * factorial(n - 1) = 24
    [src/main.rs:11] factorial(4) = 24
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    因为dbg!宏返回正在调试的值,而不是eprintln!版的返回(),不能更改代码结构.

    默认删除jemalloc

    Rust1.28发布了可选择全局分配器的方法,就开始计划把默认分配器切换到系统分配器,并允许你通过crate使用jemalloc.在Rust1.32中,终于完成了这项工作,默认,你获得程序系统分配器.
    如果想继续使用jemalloc,这里.在你的Cargo.toml中:

    jemallocator = "0.1.8"
    
    • 1

    仓库根目录:

    #[global_allocator]
    static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
    
    • 1
    • 2

    就是这样!如果不需要jemalloc,不会强加给你,如果确实需要它,只需几行代码即可.

    最终模块改进

    现在叫"统一路径",它允许以前无效的导入路径语句按非导入路径完全相同方式解析.如:

    enum Color { Red, Green, Blue }
    use Color::*;
    
    • 1
    • 2

    此代码以前未编译,因为use语句必须以super,selfcrate开头.现在编译器支持统一路径,此代码将起作用,并执行期望操作:导入use语句上方定义Color枚举的变体.

    改进宏

    首先,添加了新的字面匹配器,这里:

    macro_rules! m {
        ($lt:literal) => {};
    }
    fn main() {
        m!("some string literal");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    字面与任意类型字面匹配:串字面,数字字面,符字面.
    2018版中,也可用macro_rules宏如下用?:

    macro_rules! bar {
        ($(a)?) => {}
    }
    
    • 1
    • 2
    • 3

    ?匹配模式零次或一次重复,类似*/+.

    稳定库

    制作了19个函数const fn,且所有整数数值原语,现在都提供与字节数组间带指定字节序的转换函数.
    六个函数分别叫to__bytesfrom__bytes,其中是以下函数之一:
    ne-原生字节序
    le-小端
    be-大端

    货物特点
    Cargocargo ccargo check的别名,现在允许在注册URL中使用用户名.

    1.33.0稳定版

    改进const fn

    现在,使用const fn可做更多:

    const fn foo((x, y): (u8, u8)) { ... }
    //析构模式.
    
    • 1
    • 2

    1,let绑定与可变let绑定

    let x = 1;//绑定
    let mut x = 1;//可变绑定.
    
    • 1
    • 2

    2,(如x=y)赋值赋值符号(如x+=y)式,即使赋值目标是投影(如结构字段或索引操作,如x[3]=42)
    3,语句(如3;)

    4,还可在const fn中如下调用const unsafe fn:

    const unsafe fn foo() -> i32 { 5 }
    const fn bar() -> i32 {
        unsafe { foo() }
    }
    
    • 1
    • 2
    • 3
    • 4

    固定

    两类固定:std::pin::Pin

    类型和Unpin标记特征.std::pin的核心思想:

    有时,要保证对象不会移动,典型示例是构建自引用结构,移动指向自身指针的对象会使它们失效,从而导致未定义行为.

    Pin

    确保指针固定的.

    _导入

    现在可按_导入项目.允许导入特征的实现,且名字空间没有该名.如

    use std::io::Read as _;
    //允许,因为模块中只有一个"读取".
    pub trait Read {}
    
    • 1
    • 2
    • 3

    稳定库

    1,overflowing_{add,sub,mul,shl,shr}方法,现在是所有数值类型常量函数.
    2,rotate_left,rotate_rightwrapping_{add,sub,mul,shl,shr}方法,现在是所有数值类型常量函数.
    3,is_positiveis_negative方法现在是所有整数值类型的常量函数.
    4,所有NonZero类型的get方法现在都是const.
    5,count_ones,count_zeros,leading_zeros,trailing_zeros,swap_bytes,from_be,from_le,to_beto_le方法,现在对所有数值类型都是常量.
    6,Ipv4Addr::new现在是const函数.

    此外,这些API已稳定:
    1,unix::FileExt::read_exact_atunix::FileExt::write_all_at.
    2,Option::transposeResult::transpose
    3,convert::identity
    4,pin::Pinmarker::Unpin(如上)
    5,marker::PhantomPinned
    6,Vec::resize_withVecDeque::resize_with
    7,持续时间::as_millis,持续时间::as_micros持续时间::as_nanos.

    1.34.0稳定版

    在此版本中,Cargo支持备用注册.它与crates.io共存,因此你可编写依赖于crates.io和自定义注册表中的crate的软件.
    然而,crates.io上的仓库不能依赖外部注册.
    要使用备用注册,必须添加如下行到.cargo/config中.可在(~/.cargo/config)你的主目录中,也可在相对包目录添加此文件.

    [registries]
    my-registry = { index = "https://my-intranet:8080/git/index" }
    
    • 1
    • 2

    Cargo.toml中指定依赖项时,请用注册表项让Cargo知道想从备用注册表中取crate:

    [dependencies]
    other-crate = { version = "1.0", registry = "my-registry" }
    
    • 1
    • 2

    作为crate作者,如果想把注册crate发布到备用表,首先要用cargo login命令,把认证令牌保存到~/.cargo/credentials中:

    cargo login --registry=my-registry
    
    • 1

    然后,可用--registry标志指示发布时要使用的注册表:

    cargo publish --registry=my-registry
    
    • 1

    文档测试中用?

    RFC1937提议增加了对在fnmain(),#[test]函数和doctests中使用?符号的支持,允许它们返回OptionResult,错误值会导致fn main()中的非零退出码,而在测试时会导致测试失败.

    此版本中,在doctests完全支持?.现在,可在文档测试中编写以下内容:

    /// ```rust
    /// use std::io;
    /// let mut input = String::new();
    /// io::stdin().read_line(&mut input)?;
    /// # Ok::<(), io::Error>(())
    /// ```
    fn my_func() {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    仍必须在文档测试底部,指定要使用的错误类型.

    自定义属性接受任意令牌流

    Rust过程宏可定义使用的自定义属性.目前,限制为根据指定语法的路径和字面树,如:

    #[foo(bar)]
    #[foo = "bar"]
    #[foo = 0]
    #[foo(bar = true)]
    #[foo(bar, baz(quux, foo = "bar"))]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    过程宏不同,这些助手属性不能接受分隔符中的任意令牌流,因此无法编写#[range(0..10)]#[bound(T:MyTrait)].过程宏crate改用串来指定此语法,如#[range("0..10")].

    在该Rust版本中,#[attr($tokens)]自定义属性与一样,现在接受$tokens中的任意令牌流.

    TryFromTryInto

    允许易出错类型转换的TryFromTryInto特征已稳定.
    如,整数类型的from_be_bytes和相关带数组方法,但数据一般通过切片读入.手动转换切片和数组很麻烦.有了新的特征,就可用.try_into()内联完成.

    let num = u32::from_be_bytes(slice.try_into()?);
    
    • 1

    不会失败的转换(如u8u32),添加了Infallible类型.这样,允许对所有现有的From实现全面实现TryFrom.未来,可能想将Infallible变成!(从不)类型.

    弃用FN before_exec,选择unsafe fn pre_exec

    Unix类系统上,CommandExt::before_exec函数在调用exec之前,允许调度要运行的闭包.

    提供的闭包分叉后的子进程环境中运行.即资源(如文件描述符和内存映射区域)可能会重复.即,现在可复制非Copy类型的值到其他进程中,同时在父进程保留原值.
    这样就有可能导致未定义行为,并破坏了不重复的假设.

    因此,应按不安全标记该before_exec函数.该版本的Rust中,弃用了fn before_exec,并使用unsafe fn pre_exec.
    调用CommandExt::pre_exec时,由你确保闭包不会因无效使用这些重复项而违反库不变性.如果你提供的库与before_exec类似,请同样考虑弃用并提供不安全替代方法.

    稳定库

    1.34.0中,扩展了稳定的原子整数类型集,现在提供了从8位(AtomicU8)64位的有符号和正变体.
    以前,(如NonZeroU8)非零正整数类型是稳定的.这使得Option的大小与u8相同.在该Rust版本中,(如NonZeroI8)签名版本,已稳定下来.

    iter::from_fniter::successors函数已稳定.前者允许从Fn Mut()->Option构造迭代器.要从向量迭代弹出元素,现在可编写from_fn(||vec.pop()).
    同时,后者创建了个每个连续项都根据前一项计算的新迭代器.
    此外,这些API已稳定:

    Any::type_id
    Error::type_id
    slice::sort_by_cached_key
    str::escape_debug
    str::escape_default
    str::escape_unicode
    str::split_ascii_whitespace
    Instant::checked_add
    Instant::checked_sub
    SystemTime::checked_add
    SystemTime::checked_sub
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.34.1稳定版修复

    以下代码片中,期望方法需要dep:&D,但dep的实际类型是&&D:

    dependencies.iter().filter(|dep| dep.required());
    
    • 1

    Clippy错误地建议了.filter(Dependency::required),因为借用的差异,编译器拒绝了.

    clippy::missing_const_for_fn中的误报
    修复了missing_const_for_fn棉绒中的另一个误报.此lint没有考虑到trait实现中的函数不能是const fn.如,给定以下代码片时,触发lint:

    #[derive(PartialEq, Eq)] //警告:是一个`const_fn`
    struct Point(isize, isize);
    impl std::ops::Add for Point {
        type Output = Self;
        fn add(self, other: Self) -> Self { //警告:是一个`const_fn`
            Point(self.0 + other.0, self.1 + other.1)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.34.2稳定版

    SeanMcArthur报告了个影响标准库的安全漏洞,该漏洞导致在手动实现Error::type_id方法返回错误的TypeId时,Error::downcast系列方法执行不合理的转换,从而导致越界读取/写入等安全问题.

  • 相关阅读:
    NCV7705DQAR2G 汽车电机驱动器(NCV7705DQR2G)引脚配置
    linux驱动开发(1)前言
    锐化滤波算法及例程
    Go语言中的锁与管道的运用
    CentOS安装配置freeIPA
    Java 常用类(包装类)
    一文掌握 Go 文件的读取操作
    【深度学习环境配置】windows出现出现‘git‘ 不是内部或外部命令,也不是可运行的程序
    【MyBatis-Plus】CRUD 操作
    数据分析入门
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/134468498