[1. 개요]
슬라이스는 소유권을 갖지 않는 데이터 타입이다.
컬렉션의 연속된 일련의 요소들을 참조 할 수 있게 한다.
String::as_bytes().iter().enumerate() => (index, &item)
[2. string slice]
범위는 다음과 같다. [start, end)
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
아래와 같이 slice 범위를 정할 수 있다.
[start..end]
[..end]
[start..]
[..]
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[..]
}
함수 인자로 참조자 전달 후, 반환 값을 사용했을 때,
원본 String 메모리 해제가 먼저 발생하는 경우 컴파일 에러가 발생한다.
=> clear() 등을 이용해서 힙 소유권을 반납하지는 않지만, 힙 데이터 변경 등이 발생하는 경우,
불변참조자는 문제가 되나, 가변참조자는 문제가 되지 않는다.
스트링 리터럴은 슬라이스 이다.
=> 타입이 &str 이다.
=> 불변참조자이다.
위 함수는 다음과 같이 작성 할수도 있다.
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[..]
}
String 참조자 대신, string slice 를 넘길 수 도 있다.
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);
}
배열도 slice 화 할 수 있다.