天天看点

程序小白学Rust-----day01

 一、绪论

  只是记录学习rust的第一天,不是第一天接触rust。今天看了b站上一个up主讲解nom的视频,我觉得讲得比较好(在为数不多的rust教学视频里),视频两个小时还有一点没看完,里面的内容还是非常扎实的,需要消化一下。

附上视频的地址https://www.bilibili.com/video/BV1UK4y157BP?t=5572,

下面讲解一下今天学的知识。

二、知识点

  1.取String类型。这个是最简单的解析,只需要去掉字符串中的引号即可,最后取需要的值就行了

//"a"=x~rust"
fn extra_kv(input:&str)->IResult<&str,(&str,&str)>{
    let (input,(_,k,_,_,_,v))=tuple((
        tag("\""),
        key,
        take_until("\""),
        tag("\""),
        tag("="),
        key,
    )
    )(input)?;
    //println!("out:{:?}",out);//("\"", "a", "", "\"", "=", "x")
    Ok((input,(k,v)))
}

#[test]
fn test_extra_kv(){
    //r#  #代表这里面的字符串就是这样,不存在什么转义字符这些
    let input=r#""a"=x~rust"#;
    let (input,(k,v))=extra_kv(input).unwrap();
    assert_eq!("~rust",input);
    assert_eq!("a",k);
    assert_eq!("x",v);
}
           

2.取array类型。这个有点低端,当时还不会识别“[”,因为他只有字符串开头和结尾有,无法放到

separated_list0中,下面的代码讲了怎么把"["也消耗掉      
fn extra_arr(input:&str)->IResult<&str,Vec<&str>>{
    let (input,out)=separated_list0(
    //将字符串按逗号分开,然后用tuple处理每个分开后的子串
        tag(","),
          tuple((
              multispace0,
              tag("\""),
              key,
              take_until("\""),
              tag("\""),
          )),
    )(input)?;
    //println!("out={:?}",out);//[(" ", "\"", "a", "", "\""), ("", "\"", "b", "", "\""), ("", "\"", "c", "", "\"")]
    let mut value=vec![];
    for (_,_,v,_,_,) in out{
        value.push(v);
    }
    Ok((input,value))
}

#[test]
fn test_extra_arr(){
    let input=r#" "a","b","c" "#;
    let (input,values)=extra_arr(input).unwrap();
    assert_eq!(vec!["a","b","c"],values);
}
           

3.取array类型,加强版。其实就是引用了2的代码,然后给他套在tuple中,仔细看能看懂。

//a=["a","b","c"]
fn step_arr(input:&str)->IResult<&str,Vec<&str>>{
    let sep=separated_list0(
        tag(","),
        tuple((
            multispace0,
            tag("\""),
            key,
            take_until("\""),
            tag("\""),
        )),
    );
    let (input,(_,_,_,values,_,_,_))=tuple((
            multispace0,
            tag("["),
            multispace0,
            sep,
            multispace0,
            tag("]"),
            multispace0,
        ))(input)?;
   // println!("out={:?}",values);
    //out=("", "[", "", [("", "\"", "x", "", "\""), ("", "\"", "y", "", "\""), ("", "\"", "z", "", "\"")], "", "]", "")
    let mut value=vec![];
    for (_,_,v,_,_) in values{
        value.push(v);
    }
    Ok((input,value))
}

#[test]
fn test_step_arr(){
    let input=r#"["x","y","z"]"#;
    let (input,val)=step_arr(input).unwrap();
    assert_eq!(vec!["x","y","z"],val);
}
           

4.混合型。这个就是解决字符串中有可能是数组有可能是String类型的问题,但是字符串中只能存在两种中的一种,还没解决两个类型混合在一起解析,看明天能不能解决吧

fn extra_arr_string(input:&str)->IResult<&str,(&str,Vec<&str>)>{
    let (input,(k,_,(arr,obj)))=tuple((//k,_,(arr,obj))
            key,
            tag("="),
            tuple((opt(step_arr),opt(extra_obj))),
        ))(input)?;
    //println!("out={:?}",out);
    println!("arr={:?}",arr);
    println!("obj={:?}",obj);
    let mut value=vec![];
    if let Some(a)=arr{
        for v in a{
            value.push(v);
        }
    }
    if let Some(obj)=obj{
        value.push(obj)
    }
    Ok((input,(" ",value)))
}

#[test]
fn test_extra_arr_string(){
    let input=r#"a=["x","y","z"]"#;
    let (input,(k,v))=extra_arr_string(input).unwrap();
    assert_eq!(vec!["x","y","z"],v);
}

#[test]
fn test_extra_arr_string2(){
    let input2=r#"a="x""#;
    let (input2,(k,v))=extra_arr_string(input2).unwrap();
    assert_eq!(vec!["x"],v);
}
           

三、小结

    学rust这帮人是真的神仙,研究时间复杂度毫秒已经不能满足他们了,已经在思考把程序跑到微秒了,这还是我无法触及的。通过今天视频的学习,nom在脑子里已经有那么回事了,现在就是逐步处理更复杂的字符串了。