Rust 1.38.0 于2019-09-26发布,我们来看下有哪些更新。
盘它~
要想盘,先更新:
rustup update stable
mac OS更新,如果使用brew安装的,那么恭喜你,现在brew上面只能更新到1.37.0:
brew upgrade rust
#[global_allocator] 宏属性
这个属性在之前就已经存在了,本次允许在嵌套模块甚至是匿名模块中使用。如果是我们是初学的话不一定会用到,它支持我们自定义一个内存分配和释放的一个分配器,在声明static变量时可以使用。
#[deprecated] 宏属性
这个宏用于声明将要弃用的内容。
举例:
#[deprecated]
fn get_type<T>(_s: T) -> &'static str {
return type_name::<T>();
}
fn main() {
let b = String::from("sd");
println!("{}", get_type(b));
}
---
// 调用输出,会提示将被弃用,但是可以正常使用,
warning: use of deprecated item 'get_type'
--> src/main.rs:13:20
|
13 | println!("{}", get_type(b));
| ^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
alloc::string::String
猜测:IDE应该后续会支持更新代码样式,类似于php中的@deprecated,加入后会使用 删除线 的样式。
Pipelined compilation(管道式编译)
重点在于Cargo在编译整个依赖包以及依赖链时是通过获取依赖包元数据后接续获取下一个依赖的元数据,可以同步进行编译,最后编译我们的二进制应用。
对于过去默认的编译:
meta meta
[-libA----|--------][-libB----|--------][-binary-----------]
0s 5s 10s 15s 20s 30s
引入管道式编译后:
[-libA----|--------]
[-libB----|--------]
[-binary-----------]
0s 5s 10s 15s 25s
可以节省一部分编译时间,对于较大的框架、依赖较多会很明显,对单独的依赖包并没有什么特别的功效。
(管道式编译中的两个小例子来自:https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199)
std::any::type_name (类型获取)
从前基本都是通过报错来查看类型,就比如:
fn main() {
let a = 3;
test(a);
}
fn test(s: &str) {}
---
error[E0308]: mismatched types
--> src/main.rs:6:10
|
6 | test(a);
| ^ expected &str, found integer
|
= note: expected type `&str`
found type `{integer}`
现在可以这样,可以说还是比较好用的。
fn get_type<T>(_s: T) -> &'static str {
return type_name::<T>();
}
fn main() {
let b = String::from("sd");
println!("{}", get_type(b));
}
----
alloc::string::String
type_name的结构:
特性名称“type_name”,从1.38.0版本开始稳定,非稳定版名称“const_type_name”,返回一个静态生命周期的字符串引用。
#[stable(feature = "type_name", since = "1.38.0")]
#[rustc_const_unstable(feature = "const_type_name")]
pub const fn type_name<T: ?Sized>() -> &'static str {
#[cfg(bootstrap)]
unsafe {
intrinsics::type_name::<T>()
}
#[cfg(not(bootstrap))]
intrinsics::type_name::<T>()
}
mem::{uninitialized, zeroed} (即将移除)
建议使用MayBeUninit<T>来替换。
#[allow(missing_debug_implementations)]
#[stable(feature = "maybe_uninit", since = "1.36.0")]
// Lang item so we can wrap other types in it. This is useful for generators.
#[cfg_attr(not(bootstrap), lang = "maybe_uninit")]
#[derive(Copy)]
#[repr(transparent)]
pub union MaybeUninit<T> {
uninit: (),
value: ManuallyDrop<T>,
}
举例:
use std::mem::{self, MaybeUninit};
let x: i32 = unsafe { mem::uninitialized() };
let y: i32 = unsafe { mem::zeroed() };
let z: i32 = unsafe { MaybeUninit::uninit().assume_init() };
println!("{},{},{}", x, y, z);
---
32766,0,0
各平台的编译支持
- UWP (Universal Windows Apps) 平台.
- 其他的一些linux平台,但是部分支持不完全。
其他的更新
- ascii::EscapeDefault 实现了Clone和Display trait。
- derive支持的一些宏属性trait本次实现了可以在其自身trait定义的路径内使用,内置的一些宏也可以在std::core内使用。
- str::Chars实现了Debug trait。
#[stable(feature = "chars_debug_impl", since = "1.38.0")]
impl fmt::Debug for Chars<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Chars(")?;
f.debug_list().entries(self.clone()).finish()?;
write!(f, ")")?;
Ok(())
}
}
- slice::{concat, connect, join} 本次除了&T之外还可以接受&[T]类型。贴一个官方的例子:
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
这里&[0,0][..] 的类型就是&[i32]。
- *const T 和 *mut T 本次实现了 marker::Unpin trait,实现了对于固定的数据的安全移动,
- 增加所有数字的欧几里得计算余数和除法(div_euclid,rem_euclid),看一个小例子:
let a = -4_i32;
let b = 3_i32;
let ret = a.div_euclid(b);
let rem = a.rem_euclid(b);
println!("{}, {}", ret, a / b);
println!("{}, {}", rem, a % b);
---
-2, -1
2, -1
- thread::AccessError 本次更新支持了Clone,Copy,Eq,PartialEq。AccessError是由thread::LocalKey的try_with方法返回的。看下定义:
#[stable(feature = "thread_local_try_with", since = "1.26.0")]
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct AccessError {
_private: (),
}
- iter::{StepBy,Peekable,Take} 本次更新实现了DoubleEndedIterator(一个双头迭代器)
详细信息可见:
RELEASES NOTE:https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1380-2019-09-26
官方版本发布摘要:https://blog.rust-lang.org/2019/09/26/Rust-1.38.0.html