前言
rust 代码确实简介,但是各种操作做层出不穷,这里记录一下一些难以理解的晦涩语法。
正文
奇怪的省略值。
fn main() {let numbers = (2, 4, 8, 16, 32);match numbers {(first, .., last) => {println!("Some numbers: {}, {}", first, last);},}
}
…可以省略元组或者接头体的一些无关参数,子啊这个元组中,4.8.16 是我们不关注的,所以可以省略匹配,只匹配第一个和最后一个,所以就拿到了2和16.
多层嵌套的match语法
?号的嵌套操作
?其实更像是一个宏,可以替换成
let f = funx()?
//等价于
let f = match funx() {Ok(data)=> data,Err(e) => return Err(e),
但是嵌套到循环中就比较让人疑惑的
fn divide(a: i32, b: i32) -> Result<Option<i32>, String> {if b == 0 {return Err("Division by zero".to_string());}Ok(Some(2))
}fn calculate(a: i32, b: i32) -> Result<i32, String> {let mut tmp = 2;while let Some(i) = divide(a, tmp)?{println!("=====: {:?}", i);tmp = tmp -1}Ok(3)
其实这里类似于一个loop循环,只是加入了err强制返回操作
iter的神奇操作
//frame_data 类型是BTreeMap
let frame_data = BTreeMap::new()frame_data.iter().skip_while(|(&output_frameno, _)| {output_frameno < self.output_frameno}).find(|(_, data)| data.is_some()).map(|(&output_frameno, _)| output_frameno).ok_or(EncoderStatus::NeedMoreData)?; // TODO: doesn't play well with the below check?
因为BTreeMap类型是k-v数据map。所以iter后,会变成一种rust的元组类型,无论在后面的各种操作,都可以通过闭包来处理,map是把k-v元组转换成k。
令人迷惑的into()
rust 是类型推断的,并且类的函数可以在各种地方添加,甚至可以让一个类无缘无故的拥有一些特性,而into则是鲜明的例子。into代码如下:
// From implies Into
#[stable(feature = "rust1", since = "1.0.0")]
impl<T, U> Into<U> for T
whereU: From<T>,
{/// Calls `U::from(self)`.////// That is, this conversion is whatever the implementation of/// <code>[From]<T> for U</code> chooses to do.#[inline]fn into(self) -> U {U::from(self)}
}// From (and thus Into) is reflexive
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> From<T> for T {/// Returns the argument unchanged.#[inline(always)]fn from(t: T) -> T {t}
}
这段代码是任何的T(任何一个struct,都可以调用)都拥有了Into这个trait(内部有Into方法)。只是这个方法的返回值必须实现From这个trait。通俗的说,我想让结构体A。变成B,我只用把B实现From这个trait。就可以直接调用A的into函数。
这种思考方式非常符合人类的思维模式,但是却很不面向对象。