html5网站建设平台,宝安网站-建设深圳信科,江苏省建设工程设计施工图审核中心网站,网站外网访问怎么做路由器端口映射1.38.0
流水编译
要编译仓库,编译器不需要完全构建依赖项.相反,只需要它们的元数据(即类型,依赖关系,导出列表). 在编译过程的早期生成此元数据.从Rust1.38.0开始,Cargo利用这一点,在准备好元数据后立即自动开始构建依赖的仓库.
检查错误使用mem::{uninitialize…1.38.0
流水编译
要编译仓库,编译器不需要完全构建依赖项.相反,只需要它们的元数据(即类型,依赖关系,导出列表). 在编译过程的早期生成此元数据.从Rust1.38.0开始,Cargo利用这一点,在准备好元数据后立即自动开始构建依赖的仓库.
检查错误使用mem::{uninitialized, zeroed}
尚未弃用mem::uninitialized;.但是,从1.38.0开始,rustc使用mem::uninitialized或mem::zeroed检查一小类错误初化.
对某些(如T和BoxT)类型,包含全0位模式是未定义行为. 因此,使用mem::uninitialized或mem::zeroed初化这些类型之一是错误的,使用其中一个函数初化时,无论是直接还是按较大结构成员初化,新检查器都会发出警告.
检查是递归的,因此以下代码发出警告:
struct WrapT(T);
struct Outer(WrapWrapWrapBoxi32);
struct CannotBeZero {outer: Outer,foo: i32,bar: f32
}
...
let bad_value: CannotBeZero unsafe { std::mem::uninitialized() };Rust有更多不能为零的类型,特别是NonNullT和NonZeroT.目前,不检查使用mem::uninitialized或mem::zeroed初化这些结构.
检查并不涵盖所有不合理使用mem::uninitialized或mem::zeroed的情况,只是帮助识别绝对错误的代码.仍应移动所有代码以改用MaybeUninit.
#[deprecated]宏
现在可用弃用宏来弃用宏
std::any::type_name
对调试,取类型名有时很有用.如,在泛型代码中,想在运行时查看函数的已实例化类型参数的具体类型.现在可用std::any::type_name完成此操作:
fn gen_valueT: Default() - T {println!(初化了实例{}, std::any::type_name::T());Default::default()
}
fn main() {let _: i32 gen_value();let _: String gen_value();
}这打印:
初化i32的实例
初化alloc::string::String的实例更改库
1,现在除了T之外,slice::{concat,connect,join}还接受[T]. 2,*const T和*mut T现在实现了marker::Unpin. 3,Arc[T]和Rc[T]现在实现了FromIteratorT. 4,iter::{StepBy,Peekable,Take}现在实现了DoubleEndedIterator.
此外,已稳定下来这些功能: 1,*const T::cast和*mut T::cast 2,持续时间(Duration)::as_secs_f32和持续时间::as_secs_f64 3,持续时间::div_f32和持续时间::div_f64 4,持续时间::from_secs_f32和持续时间::from_secs_f64 5,持续时间::mul_f32和持续时间::mul_f64 6,余数和除法运算,对所有整数原语的div_euclid,rem_euclid.还提供检查,溢出和包装版本.
1.39.0稳定版
.await结束了,async fn在此
在Rust1.39.0中,很高兴地宣布async/.await已稳定!即,可定义异步函数和块,并.await它们. 可通过编写async fn而不是fn来引入异步函数,只是调用时返回Future.该Future是个暂停计算,可通过.await它来完成它.此外,
async fn
async { ... }
async move { ... }可定义异步字面. 另见这里.
对匹配警卫中按移动绑定的引用
在Rust中匹配模式时,可如下绑定变量: 1,按引用,可是不变,也可是可变的.可显式,如通过ref my_var或ref mutmy_var.不过,一般,可自动推导绑定模式. 2,按值或按复制(绑定变量类型实现Copy时)或按移动.
以前在匹配式的if守卫中,Rust会禁止按移动绑定共享引用.即会拒绝以下代码:
fn main() {let array: Box[u8; 4] Box::new([1, 2, 3, 4]);match array {nums
//----nums按移动绑定if nums.iter().sum::u8() 10
//------.iter()隐式取nums引用. {drop(nums);
//-----------nums按移动绑定,所以有所有权.}_ unreachable!(),}
}在Rust1.39.0中,编译器现在接受了上面的代码片.
函数参数的属性
在Rust1.39.0中,现在允许在函数,闭包和函数指针的参数上添加属性.在此之前,可能已写过:
#[cfg(windows)]
fn len(slice: [u16]) - usize {slice.len()
}
#[cfg(not(windows))]
fn len(slice: [u8]) - usize {slice.len()
}…你现在可更简洁地写:
fn len(#[cfg(windows)] slice: [u16], //在Windows上使用此参数.在其他地方,使用下面.#[cfg(not(windows))] slice: [u8], //
) - usize {slice.len()
}可在此位置使用的属性包括: 1,条件编译:cfg和cfg_attr 2,控制检查:允许,警告,拒绝和禁止 3,应用至项的过程宏属性使用的助手属性.
借用检查器(略). 标准库中的更多常量函数 在Rust1.39.0中,以下函数变成了const fn: 1,Vec::new,String::new和LinkedList::new 2,str::len,[T]::len和str::as_bytes 3,ABS,wrapping_abs和overflowing_abs
标准库的新增内容
以下函数已稳定下来: 1,Pin::into_inner 2,Instant::checked_duration_since和Instant::saturating_duration_since
1.40.0稳定版
#[non_exhaustive]结构,枚举和变体
附加到结构或枚举变体时,#[non_exhaustive]属性,阻止定义它的仓库外部的代码,构造所述结构或变体.为了避免未来破坏,其他仓库也无法在字段上完全匹配.
以下示例说明了beta中依赖于alpha的错误:
//alpha/lib.rs:
#[non_exhaustive]
struct Foo {pub a: bool,
}
enum Bar {#[non_exhaustive]Variant { b: u8 }
}
fn make_foo() - Foo { ... }
fn make_bar() - Bar { ... }//beta/lib.rs:
let x Foo { a: true }; //~ 错误
let Foo { a } make_foo(); //~ 错误// 添加更多字段,beta仍编译
let Foo { a, .. } make_foo(); //~ OKlet x Bar::Variant { b: 42 }; //~ 错误
let Bar::Variant { b } make_bar(); //~ 错误
let Bar::Variant { b, .. } make_bar(); //~ 好
//仍编译.背后是,对#[non_exhaustive]版的结构或枚举变体,构造器的可见性被降级到pub(crate),从而阻止在定义它的仓库之外访问它.
#[non_exhaustive]的一个更重要方面是它也可附加到枚举自身.如标准库中取的Ordering:
#[non_exhaustive]
pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst }这里,#[non_exhaustive]确保未来可添加更多变体.编译器拒绝:
match ordering {//如果添加了新的变体,这是个错误,这在编译器升级时会突然中断.Relaxed | Release | Acquire | AcqRel | SeqCst {/*逻辑*/}
}而,其他仓库需要用如_添加通配符分支来考虑更多变体:
match ordering {Relaxed | Release | Acquire | AcqRel | SeqCst { /*...*/ }//好;如果添加更多变体,就不会破坏._ { /*逻辑*/ }
}改进宏和属性
包括: 1,在类型环境中,调用mac!()过程宏. 如,你可编写:
type Foo expand_to_type!(bar);
//expand_to_type是过程宏.2,extern{...}块中的宏. 包括bang!()宏,如:
macro_rules! make_item { ($name:ident) { fn $name(); } }
extern {make_item!(alpha);make_item!(beta);
}3,现在还支持extern{...}块中项的过程宏属性:
extern C {//假设扩展为fn foo();.#[my_identity_macro]fn foo();
}4,产生macro_rules!过程宏中的项. 类似(mac!())的函数和(#[mac])属性宏,现在都可生成macro_rules!项目.
5,$m:meta匹配器支持任意令牌流值. 即,以下内容现在有效:
macro_rules! accept_meta { ($m:meta) {} }
accept_meta!( my::path );
accept_meta!( my::path lit );
accept_meta!( my::path ( a b c ) );
accept_meta!( my::path [ a b c ] );
accept_meta!( my::path { a b c } );标准库中的更多常量函数 在Rust1.40.0中,以下函数变成了const fn: 1,正整数版的is_power_of_two.
标准库的新增内容
在Rust1.40.0中,稳定了以下函数和宏: 1,todo!() unimplemented!()的更短,更可读,更方便的版本. 2,slice::重复(repeat) 通过n次重复切片来创建VecT. 3,mem::take 此函数从可变引用中取值,并用类型默认值替换它.类似Option::take和Cell::take,并为mem::replace(mut dst,Default::default())提供了一个方便的简写. 4,BTreeMap::get_key_value和HashMap::get_key_value 返回与提供的键对应的键值对.
5,可选(Option)::as_deref,可选::as_deref_mut 类似Option::as_ref和Option::as_mut,但也分别使用Deref和DerefMut,因此opt_box.as_deref()和opt_box.as_deref_mut(),其中opt_box:OptionBoxT分别生成OptionT和Optionmut;T.
6,可选::flatten
此函数把OptionOptionT变平为OptionT,对Some(Some(x))变平为Some(x),否则为None.该函数类似Iterator::flatten.
7,UdpSocket::peer_addr
返回此套接字连接到的远端的套接字地址. 8,{f32,f64}::to_be_bytes,{f32,f64}::to_le_bytes,{f32,f64}::to_ne_bytes,{f32,f64}::from_be_bytes,{f32,f64}::from_le_bytes和{f32,f64}::from_ne_bytes
按big-endian(network),little-endian和native-endian字节序排列,并按字节数组返回浮点数的内存表示.
1.41.0稳定版
放宽实现特征的限制
在Rust1.41.0之前,孤儿规则过于严格,妨碍了组合.如,假设你的仓库定义了BetterVecT结构,且想要转换结构为标准库的VecT. 要写的代码是:
implT FromBetterVecT for VecT {//...
}是如下模式的一个实例:
implT ForeignTraitLocalType for ForeignTypeT {//...
}在Rust1.40.0中,孤立规则会禁止该impl,因为From和Vec都是在标准库中定义的,这与当前的仓库无关. 有些方法如新类型模式,可绕过这些限制,但它们一般很麻烦.
虽然From和Vec仍是外部的,但特征(本例为From)是由局部类型参数化的.因此,Rust1.41.0允许该实现.
过时时,cargo install更新安装包
从Rust1.41.0开始,如果自安装以来发布了新版本,cargo install也会更新现有安装的仓库版本.此版之前,必须传递即使二进制仓库是最新的,也会重装的--force标志.
不易冲突的Cargo.lock格式
Rust1.41.0为文件引入了新的格式
在FFI中使用BoxT时的更多保证
从Rust1.41.0开始,声明T:Sized的BoxT现在与C语言的(T*)指针类型兼容.
因此,如果有从C调用的externC的Rust函数,你的Rust函数现在对特定T,可指定BoxT,同时对相应函数,用C语言中的T*. 如,在C端,可能有:
//C头文件,返回所有权给调用者.
struct Foo* foo_new(void);
//从调用者取所有权;使用NULL调用时为空操作.
void foo_delete(struct Foo*);而在Rust方面,你:
#[repr(C)]
pub struct Foo;
#[no_mangle]
pub extern C fn foo_new() - BoxFoo {Box::new(Foo)
}
//用Option_表示NULL的可能性.
#[no_mangle]
pub extern C fn foo_delete(_: OptionBoxFoo) {}但注意,虽然BoxT和T*有相同的表示和ABI,但BoxT仍必须为非空,对齐且准备好由全局分配器释放.为此,最好只使用全局分配器的Box.
更改库
在Rust1.41.0中,标准库补充: 1,Result::map_or和Result::map_or_else方法已稳定. 2,与Option::map_or和Option::map_or_else类似,
.map(|val| process(val)).unwrap_or(default)是上面的快捷方式.
3,(如果是较小整数宽度)NonZero*数值现在实现FromNonZero*.如,NonZeroU16现在实现FromNonZeroU8. 4,弱针上的weak_count和strong_count方法已稳定.
std::rc::Weak::weak_count
std::rc::Weak::strong_count
std::sync::Weak::weak_count
std::sync::Weak::strong_count这些方法分别返回分配的弱(rc::WeakT和sync::WeakT)或强(RcT和ArcT)指针数. MaybeUninitT现在实现了fmt::Debug.
在Rust1.41.0中,因为静态值内部表示有些变化,借用检查器意外地允许了一些不健全的程序.即,借用检查器不会检查静态项是否有正确类型. 这反之又允许分配生命期小于静态的临时变量给静态变量:
static mut MY_STATIC: static u8 0;
fn main() {let my_temporary 42;unsafe {//在1.41.0中错误地允许了:MY_STATIC my_temporary;}
}此问题已在1.41.1中得到解决.
在复制实现中遵守静态生命期
从Rust1.0开始,一直编译以下错误程序:
#[derive(Clone)]
struct Fooa(a u32);
impl Copy for Foostatic {}
fn main() {let temporary 2;let foo (Foo(temporary),);drop(foo.0); //必须访问foo的一部分.drop(foo.0); //也可以索引数组.
}在Rust1.41.1中,已修复此问题.
错误原因是对某些a,Fooa仅在a:static时实现Copy.但是,带0生命期的临时变量不会超过static存活,因此Foo0不是Copy,因此第二次使用drop应该是个错误.
1.42.0稳定版
选项和结果恐慌消息中的有用行号
unwrap_err,expect,及expect_err和相应Result类型函数, 所有这八个函数都会生成带行号的恐慌消息.新的错误消息如下: main线程,在None值上调用Option::unwrap()时恐慌,src/main.rs:2:5即在src/main.rs的第2行无效调用了unwrap.
子切片模式
允许在切片上匹配.像这样:
fn foo(words: [str]) {match words {[] println!(empty slice!),[one] println!(one element: {:?}, one),[one, two] println!(two elements: {:?} {:?}, one, two),_ println!(多少元素?),}
}虽允许在切片上匹配,但相当有限.必须选择想支持的确切尺寸,且要加分支. 在Rust1.42中,扩展支持切片的部分匹配,这里:
fn foo(words: [str]) {match words {[Hello, World, !, ..] println!(Hello World!),[Foo, Bar, ..] println!(Baz),rest println!({:?}, rest),}
}因为与切片的其余部分匹配,..叫其余模式.上例在切片末尾使用其余模式,但也可按其他方式用它:
fn foo(words: [str]) {match words {//最后元素必须是!,忽略其他元素.[.., !] println!(!!!),//最后元素必须是z,start是除最后元素之外的所有元素的切片.[start .., z] println!(starts with: {:?}, start),//第一个元素必须是a,end是除第一个元素之外的所有元素的切片.[a, end ..] println!(ends with: {:?}, end),rest println!({:?}, rest),}
}更多
matches!
稳定了一个新的matches!宏.此宏接受式及模式,如果模式与式匹配,则返回true.即:
//使用匹配式:
match self.partial_cmp(other) {Some(Less) true,_ false,
}
//使用matches!宏:
matches!(self.partial_cmp(other), Some(Less))还可用|模式和if防护:
let foo f;
assert!(matches!(foo, A..Z | a..z));
let bar Some(4);
assert!(matches!(bar, Some(x) if x 2));现在可使用proc_macro::TokenStream;
在Rust2018中,删除了extern crate的需求.但是过程宏有点特殊,要写过程宏时,仍需要
extern crate proc_macro;此版本中,如果使用Cargo,则在使用2018版时不再需要此行;可像使用其他仓库一样使用.
库
1,iter::EmptyT现在对T实现发送和同步. 2,Pin::{map_unchecked,map_unchecked_mut}不再需要返回类型实现Sized. 3,io::Cursor现在实现了PartialEq和Eq. 4,Layout::new现在是const.
稳定的API
1,CondVar::wait_while和CondVar::wait_timeout_while 2,DebugMap::key和DebugMap::value 3,ManuallyDrop::take 4,PTR::slice_from_raw_parts_mut和PTR::slice_from_raw_parts