문제
문자열을 입력받아 그 문자열의 첫 번째 단어를 반환하는 함수를 작성하시오.
- 바이트 배열을 이용하기
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() }
fn main() { let mut s = String::from("hello world"); let word = first_word(&s); // word는 5를 갖게 될 것입니다. s.clear(); // 이 코드는 String을 비워서 ""로 만들게 됩니다. // word는 여기서 여전히 5를 갖고 있지만, 5라는 값을 의미있게 쓸 수 있는 스트링은 이제 없습니다. // word는 이제 완전 유효하지 않습니다! }
스트링 슬라이스
let s = String::from("hello world"); let hello = &s[0..5]; let world = &s[6..11];
&s[..5]
,&s[0..]
,&s[..]
모두 다 사용 가능. 생략하면 처음 인덱스와 끝 인덱스가 됨.
- 스트링 슬라이스를 사용하기
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); }
17:6 error: cannot borrow `s` as mutable because it is also borrowed as immutable [E0502] s.clear(); // Error! ^ 15:29 note: previous borrow of `s` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `s` until the borrow ends let word = first_word(&s); ^ 18:2 note: previous borrow ends here fn main() { } ^
스트링 리터럴 = 슬라이스
let s = "Hello, world!";
- 위에서
s
의 자료형은&str
로, 불변 참조자인 스트링 슬라이스이다.
파라미터로서의 스트링 슬라이스
&str
(스트링 슬라이스)는 스트링 리터럴과String
을 모두 처리할 수 있음.
fn first_word(s: &str) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[0..i]; } } &s[..] } fn main() { let my_string = String::from("hello world"); // first_word가 `String`의 슬라이스로 동작합니다. let word = first_word(&my_string[..]); let my_string_literal = "hello world"; // first_word가 스트링 리터럴의 슬라이스로 동작합니다. let word = first_word(&my_string_literal[..]); // 스트링 리터럴은 *또한* 스트링 슬라이스이기 때문에, // 아래 코드도 슬라이스 문법 없이 동작합니다! let word = first_word(my_string_literal); }
그 밖의 슬라이스
let a = [1, 2, 3, 4, 5]; let slice = &a[1..3];
slice
는&[i32]
자료형이다.