• 2.6 Rust Slice Type


    字符串操作

    fn first_word(s: &String) -> usize {
        let bytes = s.as_bytes();
    
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return i;
            }
        }
    
        s.len()
    }

    Because we need to go through the String element by element and check whether a value is a space, we’ll convert our String to an array of bytes using the as_bytes method

     For now, know that iter is a method that returns each element in a collection and that enumerate wraps the result of iter and returns each element as part of a tuple instead. The first element of the tuple returned from enumerate is the index, and the second element is a reference to the element. This is a bit more convenient than calculating the index ourselves.

    Because the enumerate method returns a tuple, we can use patterns to destructure that tuple, just like everywhere else in Rust. So in the for loop, we specify a pattern that has i for the index in the tuple and &item for the single byte in the tuple. Because we get a reference to the element from .iter().enumerate(), we use & in the pattern.

    Inside the for loop, we search for the byte that represents the space by using the byte literal syntax. If we find a space, we return the position. Otherwise, we return the length of the string by using s.len()

    fn main() {
        let mut s = String::from("hello world");
    
        let _word = first_word(&s); // word will get the value 5
    
        println!("{},{}",s,_word);
        s.clear(); // this empties the String, making it equal to ""
    
        // word still has the value 5 here, but there's no more string that
        // we could meaningfully use the value 5 with. word is now totally invalid!
    }
    
    
    fn first_word(s: &String) -> usize {
        let bytes = s.as_bytes();
    
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return i;
            }
        }
    
        s.len()
    }

    字符串切片

    str[index..end_position]

    index:字符索引位置,从0开始

    end_position:字符位置,从1开始

    let s = String::from("hello world");
    
    let hello = &s[0..5];
    let world = &s[6..11];

    With Rust’s .. range syntax, if you want to start at the first index (zero), you can drop the value before the two periods. In other words, these are equal:

    let s = String::from("hello");
    
    let slice = &s[0..2];
    let slice = &s[..2];

    By the same token, if your slice includes the last byte of the String, you can drop the trailing number. That means these are equal:

    let s = String::from("hello");
    
    let len = s.len();
    
    let slice = &s[3..len];
    let slice = &s[3..];

    You can also drop both values to take a slice of the entire string. So these are equal:

    let s = String::from("hello");
    
    let len = s.len();
    
    let slice = &s[0..len];
    let slice = &s[..];

    Note: String slice range indices must occur at valid UTF-8 character boundaries. If you attempt to create a string slice in the middle of a multibyte character, your program will exit with an error.

     切片字符串操作

    fn first_word(s: &String) -> &str {
        let bytes = s.as_bytes();
    
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return &s[0..i];
            }
        }
    
        &s[..]
    }

    第一种方式为直接对字符串本身进行操作,没有第二个变量产生,切片则是新定义了一个变量,指向了原字符串的部分内容。当作用域发生变化时,它们的不同就会显现出来。

     下面这一段代码是正确的

    fn main() {
        let mut s = String::from("hello world");
    
        let word = first_word(&s);
    
        s.clear(); // error!
    
        println!("the first word is: {}", word);
    }
    
    fn first_word(s: &String) -> usize {
        let bytes = s.as_bytes();
    
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return i;
            }
        }
    
        s.len()
    }

    然而官网上则说这段代码是有问题的,可能是rust版本升级后此处做了改动

    fn main() {
        let my_string = String::from("hello world");
    
        // first_word works on slices of `String`s
        let word = first_word(&my_string);
    
        //let my_string_literal = "hello world";
    
        // first_word works on slices of string literals
        //let word = first_word(&my_string_literal);
    
        // Because string literals *are* string slices already,
        // this works too, without the slice syntax!
        //let word = first_word(my_string_literal);
        println!("{}",word);
    }
    
    fn first_word(s: &String) -> &str {
        let bytes = s.as_bytes();
    
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return &s[0..i];
            }
        }
    
        &s[..]
    }
  • 相关阅读:
    游戏大厅升级日记 第3天
    GamePlatform 2.0 b的数据库脚本
    会xiaotie的一个TCP问题
    求助,基于WCF的聊天室,在用户非法掉线后,不能将Disconnected事件通知到Server
    SQL Server 聚合函数 (方差和标准差)
    体验了一把vs2008
    老罗语录打包下载(保证能下载)
    局域网单独一台机器无法ping通网关故障的解决方法
    vs2005中遇到的一个奇怪的错误 
    Page.RegisterClientScriptBlock和Page.RegisterStartupScript有何区别
  • 原文地址:https://www.cnblogs.com/perfei/p/10695393.html
Copyright © 2020-2023  润新知