武漢肥貓科技商城網(wǎng)站建設(shè)北京專業(yè)seo公司
1.38.0
流水編譯
要編譯倉庫
,編譯器不需要完全
構(gòu)建依賴項(xiàng)
.相反,只需要它們的"元數(shù)據(jù)
"(即類型,依賴關(guān)系,導(dǎo)出列表
).
在編譯過程的早期生成此元數(shù)據(jù)
.從Rust1.38.0
開始,Cargo
利用這一點(diǎn),在準(zhǔn)備好元數(shù)據(jù)
后立即
自動開始構(gòu)建依賴的倉庫
.
檢查錯(cuò)誤使用mem::{uninitialized, zeroed}
尚未棄用mem::uninitialized;
.但是,從1.38.0
開始,rustc
使用mem::uninitialized
或mem::zeroed
檢查一小類錯(cuò)誤
初化.
對某些(如&T
和Box<T>
)類型,包含全0
位模式是未定義行為
.
因此,使用mem::uninitialized
或mem::zeroed
初化這些類型
之一是錯(cuò)誤的,使用
其中一個(gè)函數(shù)
初化時(shí),無論是直接
還是按較大結(jié)構(gòu)成員
初化,新檢查器
都會發(fā)出警告.
檢查
是遞歸
的,因此以下
代碼發(fā)出警告:
struct Wrap<T>(T);
struct Outer(Wrap<Wrap<Wrap<Box<i32>>>>);
struct CannotBeZero {outer: Outer,foo: i32,bar: f32
}
...
let bad_value: CannotBeZero = unsafe { std::mem::uninitialized() };
Rust
有更多不能為零的類型,特別是NonNull<T>
和NonZero<T>
.目前,不檢查
使用mem::uninitialized
或mem::zeroed
初化這些結(jié)構(gòu)
.
檢查
并不涵蓋所有不合理使用mem::uninitialized
或mem::zeroed
的情況,只是幫助識別
絕對錯(cuò)誤的代碼.仍應(yīng)移動
所有代碼以改用MaybeUninit
.
#[deprecated]
宏
現(xiàn)在可用棄用宏
來棄用
宏
std::any::type_name
對調(diào)試
,取類型名
有時(shí)很有用.如,在泛型
代碼中,想在運(yùn)行時(shí)
查看函數(shù)
的已實(shí)例化
類型參數(shù)的具體類型
.現(xiàn)在可用std::any::type_name
完成此操作:
fn gen_value<T: Default>() -> T {println!("初化了實(shí)例{}", std::any::type_name::<T>());Default::default()
}
fn main() {let _: i32 = gen_value();let _: String = gen_value();
}
這打印:
初化`i32`的實(shí)例
初化`alloc::string::String`的實(shí)例
更改庫
1,現(xiàn)在除了&T
之外,slice::{concat,connect,join}
還接受&[T]
.
2,*const T
和*mut T
現(xiàn)在實(shí)現(xiàn)了marker::Unpin
.
3,Arc<[T]>
和Rc<[T]>
現(xiàn)在實(shí)現(xiàn)了FromIterator<T>
.
4,iter::{StepBy,Peekable,Take}
現(xiàn)在實(shí)現(xiàn)了DoubleEndedIterator
.
此外,已穩(wěn)定下來這些功能
:
1,<*const T>::cast
和<*mut T>::cast
2,持續(xù)時(shí)間(Duration)::as_secs_f32
和持續(xù)時(shí)間::as_secs_f64
3,持續(xù)時(shí)間::div_f32
和持續(xù)時(shí)間::div_f64
4,持續(xù)時(shí)間::from_secs_f32
和持續(xù)時(shí)間::from_secs_f64
5,持續(xù)時(shí)間::mul_f32
和持續(xù)時(shí)間::mul_f64
6,余數(shù)和除法
運(yùn)算,對所有整數(shù)原語
的div_euclid,rem_euclid
.還提供檢查,溢出和包裝
版本.
1.39.0
穩(wěn)定版
.await
結(jié)束了,async fn
在此
在Rust1.39.0
中,很高興地宣布async/.await
已穩(wěn)定!即,可定義異步函數(shù)和塊
,并.await
它們.
可通過編寫async fn
而不是fn
來引入異步函數(shù)
,只是調(diào)用時(shí)返回Future
.該Future
是個(gè)暫停計(jì)算
,可通過.await
它來完成它.此外,
async fn
async { ... }
async move { ... }
可定義異步字面.
另見這里.
對匹配警衛(wèi)中按移動
綁定的引用
在Rust
中匹配模式
時(shí),可如下綁定
變量:
1,按引用
,可是不變
,也可是可變
的.可顯式,如通過ref my_var
或ref mutmy_var
.不過,一般,可自動推導(dǎo)綁定模式
.
2,按值或按復(fù)制
(綁定變量
類型實(shí)現(xiàn)Copy
時(shí))或按移動
.
以前在匹配式
的if
守衛(wèi)中,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'`按移動綁定,所以有所有權(quán).}_ => unreachable!(),}
}
在Rust1.39.0
中,編譯器現(xiàn)在接受
了上面的代碼片.
函數(shù)參數(shù)的屬性
在Rust1.39.0
中,現(xiàn)在允許在函數(shù),閉包和函數(shù)指針
的參數(shù)上添加屬性
.在此之前,可能已寫過:
#[cfg(windows)]
fn len(slice: &[u16]) -> usize {slice.len()
}
#[cfg(not(windows))]
fn len(slice: &[u8]) -> usize {slice.len()
}
…你現(xiàn)在可更簡潔地寫:
fn len(#[cfg(windows)] slice: &[u16], //在`Windows`上使用此參數(shù).在其他地方,使用下面.#[cfg(not(windows))] slice: &[u8], //
) -> usize {slice.len()
}
可在此位置使用的屬性
包括:
1,條件編譯:cfg
和cfg_attr
2,控制檢查
:允許,警告,拒絕和禁止
3,應(yīng)用
至項(xiàng)的過程宏屬性
使用的助手屬性
.
借用檢查器(略).
標(biāo)準(zhǔn)庫中的更多常量函數(shù)
在Rust1.39.0
中,以下函數(shù)變成了const fn
:
1,Vec::new,String::new
和LinkedList::new
2,str::len,[T]::len
和str::as_bytes
3,ABS,wrapping_abs
和overflowing_abs
標(biāo)準(zhǔn)庫的新增內(nèi)容
以下函數(shù)
已穩(wěn)定下來:
1,Pin::into_inner
2,Instant::checked_duration_since
和Instant::saturating_duration_since
1.40.0
穩(wěn)定版
#[non_exhaustive]
結(jié)構(gòu),枚舉和變體
附加
到結(jié)構(gòu)或枚舉
變體時(shí),#[non_exhaustive]
屬性,阻止
定義它的倉庫
外部的代碼
,構(gòu)造所述結(jié)構(gòu)或變體
.為了避免未來破壞
,其他倉庫
也無法在字段
上完全匹配.
以下示例說明了beta
中依賴于alpha
的錯(cuò)誤:
//`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 }; //~ 錯(cuò)誤
let Foo { a } = make_foo(); //~ 錯(cuò)誤// 添加更多字段,`beta`仍編譯
let Foo { a, .. } = make_foo(); //~ OKlet x = Bar::Variant { b: 42 }; //~ 錯(cuò)誤
let Bar::Variant { b } = make_bar(); //~ 錯(cuò)誤
let Bar::Variant { b, .. } = make_bar(); //~ 好
//仍編譯.
背后是,對#[non_exhaustive]
版的結(jié)構(gòu)或枚舉變體
,構(gòu)造器
的可見性被降級到pub(crate)
,從而阻止
在定義它的倉庫
之外訪問它.
#[non_exhaustive]
的一個(gè)更重要
方面是它也可附加
到枚舉
自身.如標(biāo)準(zhǔn)庫中取的Ordering
:
#[non_exhaustive]
pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst }
這里,#[non_exhaustive]
確保未來可添加
更多變體.編譯器拒絕:
match ordering {//如果添加了新的變體,這是個(gè)錯(cuò)誤,這在編譯器升級時(shí)會突然中斷.Relaxed | Release | Acquire | AcqRel | SeqCst => {/*邏輯*/}
}
而,其他
倉庫需要用如_
添加通配符分支
來考慮更多變體
:
match ordering {Relaxed | Release | Acquire | AcqRel | SeqCst => { /*`...`*/ }//好;如果添加更多變體,就不會破壞._ => { /*邏輯*/ }
}
改進(jìn)宏和屬性
包括:
1,在類型環(huán)境中,調(diào)用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,現(xiàn)在還支持extern{...}
塊中項(xiàng)的過程宏屬性
:
extern "C" {//假設(shè)擴(kuò)展為`'fn foo();'`.#[my_identity_macro]fn foo();
}
4,產(chǎn)生macro_rules!
過程宏中的項(xiàng).
類似(mac!())
的函數(shù)和(#[mac])
屬性宏,現(xiàn)在都可生成macro_rules!
項(xiàng)目.
5,$m:meta
匹配器支持任意令牌流值
.
即,以下內(nèi)容
現(xiàn)在有效
:
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 } );
標(biāo)準(zhǔn)庫中的更多常量函數(shù)
在Rust1.40.0
中,以下函數(shù)變成了const fn
:
1,正整數(shù)
版的is_power_of_two
.
標(biāo)準(zhǔn)庫的新增內(nèi)容
在Rust1.40.0
中,穩(wěn)定了以下函數(shù)和宏
:
1,todo!()
unimplemented!()
的更短,更可讀,更方便
的版本.
2,slice::重復(fù)(repeat)
通過n
次重復(fù)切片
來創(chuàng)建Vec<T>
.
3,mem::take
此函數(shù)
從可變引用
中取值,并用類型
默認(rèn)值替換
它.類似Option::take
和Cell::take
,并為mem::replace(&mut dst,Default::default())
提供了一個(gè)方便的簡寫.
4,BTreeMap::get_key_value
和HashMap::get_key_value
返回與提供的鍵
對應(yīng)的鍵值對
.
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:Option<Box<T>>
分別生成Option<&T>
和Option<&mut;T>
.
6,可選::flatten
此函數(shù)把Option<Option<T>>
變平為Option<T>
,對Some(Some(x))
變平為Some(x)
,否則為None
.該函數(shù)類似Iterator::flatten
.
7,UdpSocket::peer_addr
返回此套接字
連接到的遠(yuǎn)端
的套接字地址
.
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
字節(jié)序排列,并按字節(jié)數(shù)組
返回浮點(diǎn)數(shù)的內(nèi)存表示
.
1.41.0
穩(wěn)定版
放寬實(shí)現(xiàn)特征
的限制
在Rust1.41.0
之前,孤兒規(guī)則
過于嚴(yán)格,妨礙
了組合.如,假設(shè)你的倉庫
定義了BetterVec<T>
結(jié)構(gòu),且想要轉(zhuǎn)換結(jié)構(gòu)
為標(biāo)準(zhǔn)庫的Vec<T>
.
要寫的代碼是:
impl<T> From<BetterVec<T>> for Vec<T> {//`...`
}
是如下模式
的一個(gè)實(shí)例:
impl<T> ForeignTrait<LocalType> for ForeignType<T> {//`...`
}
在Rust1.40.0
中,孤立規(guī)則
會禁止該impl
,因?yàn)?code>From和Vec
都是在標(biāo)準(zhǔn)庫
中定義的,這與當(dāng)前的倉庫
無關(guān).
有些方法如新類型模式
,可繞過這些限制
,但它們一般很麻煩
.
雖然From
和Vec
仍是外部
的,但特征(本例為From
)是由局部類型
參數(shù)化的.因此,Rust1.41.0
允許該實(shí)現(xiàn).
過時(shí)時(shí),cargo install
更新安裝包
從Rust1.41.0
開始,如果自安裝
以來發(fā)布了新版本,cargo install
也會更新
現(xiàn)有安裝的倉庫
版本.此版之前,必須傳遞即使二進(jìn)制倉庫
是最新的,也會重裝的--force
標(biāo)志.
不易沖突的Cargo.lock
格式
Rust1.41.0
為文件引入了新的格式
在FFI
中使用Box<T>
時(shí)的更多保證
從Rust1.41.0
開始,聲明T:Sized
的Box<T>
現(xiàn)在與C語言
的(T*)
指針類型兼容.
因此,如果有從C調(diào)用的extern"C"
的Rust
函數(shù),你的Rust
函數(shù)現(xiàn)在對特定T
,可指定Box<T>
,同時(shí)對相應(yīng)
函數(shù),用C語言中的T*
.
如,在C端,可能有:
//C頭文件,返回所有權(quán)給調(diào)用者.
struct Foo* foo_new(void);
//從調(diào)用者取所有權(quán);使用`NULL`調(diào)用時(shí)為`空操作`.
void foo_delete(struct Foo*);
而在Rust
方面,你:
#[repr(C)]
pub struct Foo;
#[no_mangle]
pub extern "C" fn foo_new() -> Box<Foo> {Box::new(Foo)
}
//用`"Option<_>"`表示`NULL`的可能性.
#[no_mangle]
pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
但注意,雖然Box<T>
和T*
有相同的表示和ABI
,但Box<T>
仍必須為非空
,對齊
且準(zhǔn)備好由全局分配器
釋放.為此,最好只使用全局
分配器的Box
.
更改庫
在Rust1.41.0
中,標(biāo)準(zhǔn)庫補(bǔ)充
:
1,Result::map_or
和Result::map_or_else
方法已穩(wěn)定.
2,與Option::map_or
和Option::map_or_else
類似,
.map(|val| process(val)).unwrap_or(default)
是上面的快捷方式.
3,(如果是較小
整數(shù)寬度)NonZero*
數(shù)值現(xiàn)在實(shí)現(xiàn)From<NonZero*>
.如,NonZeroU16
現(xiàn)在實(shí)現(xiàn)From<NonZeroU8>
.
4,弱針上的weak_count
和strong_count
方法已穩(wěn)定.
std::rc::Weak::weak_count
std::rc::Weak::strong_count
std::sync::Weak::weak_count
std::sync::Weak::strong_count
這些方法分別返回分配的弱(rc::Weak<T>
和sync::Weak<T>
)或強(qiáng)(Rc<T>
和Arc<T>
)指針數(shù).
MaybeUninit<T>
現(xiàn)在實(shí)現(xiàn)了fmt::Debug
.
在Rust1.41.0
中,因?yàn)?code>靜態(tài)值內(nèi)部表示有些變化,借用檢查器
意外地允許
了一些不健全的程序.即,借用檢查器不會檢查
靜態(tài)項(xiàng)是否有正確類型
.
這反之又允許分配生命期小于"靜態(tài)"
的臨時(shí)變量
給靜態(tài)變量:
static mut MY_STATIC: &'static u8 = &0;
fn main() {let my_temporary = 42;unsafe {//在`1.41.0`中錯(cuò)誤地允許了:MY_STATIC = &my_temporary;}
}
此問題已在1.41.1
中得到解決.
在復(fù)制
實(shí)現(xiàn)中遵守"靜態(tài)生命期
"
從Rust1.0
開始,一直編譯
以下錯(cuò)誤程序:
#[derive(Clone)]
struct Foo<'a>(&'a u32);
impl Copy for Foo<'static> {}
fn main() {let temporary = 2;let foo = (Foo(&temporary),);drop(foo.0); //必須訪問`"foo"`的一部分.drop(foo.0); //也可以`索引數(shù)組`.
}
在Rust1.41.1
中,已修復(fù)此問題.
錯(cuò)誤原因是對某些'a
,Foo<'a>
僅在'a:'static
時(shí)實(shí)現(xiàn)Copy
.但是,帶'0
生命期的臨時(shí)變量
不會超過'static'
存活,因此Foo<'0>
不是Copy
,因此第二次使用drop
應(yīng)該是個(gè)錯(cuò)誤.
1.42.0
穩(wěn)定版
選項(xiàng)
和結(jié)果
恐慌消息中的有用行號
unwrap_err,expect,及expect_err和相應(yīng)Result類型
函數(shù),
所有這八個(gè)
函數(shù)都會生成帶行號的恐慌
消息.新的錯(cuò)誤消息如下
:
`"main"`線程,在`"None"`值上"調(diào)用`'Option::unwrap()'`時(shí)恐慌`',src/main.rs:2:5`
即在src/main.rs
的第2行無效調(diào)用
了unwrap
.
子切片模式
允許在切片
上匹配.像這樣:
fn foo(words: &[&str]) {match words {[] => println!("empty slice!"),[one] => println!("one element: {:?}", one),[one, two] => println!("two elements: {:?} {:?}", one, two),_ => println!("多少元素?"),}
}
雖允許在切片
上匹配,但相當(dāng)有限
.必須選擇想支持的確切
尺寸,且要加分支
.
在Rust1.42
中,擴(kuò)展支持切片
的部分匹配
,這里:
fn foo(words: &[&str]) {match words {["Hello", "World", "!", ..] => println!("Hello World!"),["Foo", "Bar", ..] => println!("Baz"),rest => println!("{:?}", rest),}
}
因?yàn)榕c切片
的其余部分匹配,..
叫"其余模式".上例在切片
末尾使用其余
模式,但也可按其他方式
用它:
fn foo(words: &[&str]) {match words {//最后元素必須是`"!"`,忽略其他元素.[.., "!"] => println!("!!!"),//最后元素必須是`"z"`,`"start"`是除最后元素之外的`所有元素`的切片.[start @ .., "z"] => println!("starts with: {:?}", start),//第一個(gè)元素必須是`"a"`,`"end"`是除第一個(gè)元素之外的`所有元素`的切片.["a", end @ ..] => println!("ends with: {:?}", end),rest => println!("{:?}", rest),}
}
更多
matches!
穩(wěn)定了一個(gè)新的matches!
宏.此宏接受式及模式
,如果模式與式
匹配,則返回true
.即:
//使用匹配式:
match self.partial_cmp(other) {Some(Less) => true,_ => false,
}
//使用`'matches!'`宏:
matches!(self.partial_cmp(other), Some(Less))
還可用|
模式和if
防護(hù):
let foo = 'f';
assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
let bar = Some(4);
assert!(matches!(bar, Some(x) if x > 2));
現(xiàn)在可使用proc_macro::TokenStream;
在Rust2018
中,刪除了extern crate
的需求.但是過程宏
有點(diǎn)特殊,要寫過程宏時(shí),仍需要
extern crate proc_macro;
此版本中,如果使用Cargo
,則在使用2018
版時(shí)不再需要此行
;可像使用
其他倉庫一樣使用.
庫
1,iter::Empty<T>
現(xiàn)在對T
實(shí)現(xiàn)發(fā)送和同步
.
2,Pin::{map_unchecked,map_unchecked_mut}
不再需要返回類型
實(shí)現(xiàn)Sized
.
3,io::Cursor
現(xiàn)在實(shí)現(xiàn)了PartialEq
和Eq
.
4,Layout::new
現(xiàn)在是const
.
穩(wěn)定的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