티스토리 뷰
소유권을 갖지 않는 또다른 데이터 타입은 슬라이스이다.
슬라이스는 collection 전체가 아닌 collection의 연속된 일련의 요소들을 참조할 수 있게 함.
//소유권을 갖지 않는 데이터타입.
fn first_word(s : &String) -> usize {
//바이트 배열로 변환
let bytes = s.as_bytes();
//iter() : 반복자 //enumerate() : 튜플형식으로 반환
//bytes의 인덱스 i, 참조값 &item
for(i, &item) in bytes.iter().enumerate(){
if item == b' '{
return i;
}
}
s.len()
}
pub fn run(){
let mut s = String::from("te st");
let len = first_word(&s);
s.clear();
println!("{}", len);
}
여기서 run()함수를 실행시켰을때, s에 문자열 "te st"가 할당되고, 변수 len에는 first_word가 실행된 결과인 2가 할당될 것이다.
그 다음 first_word에 argument로 넘긴 s의 값을 clear로 내용을 비우고 ""상태가 되게 한다.
len은 여전히 값을 가지고 있지만, 변수 s와 싱크가 맞지 않게 된다.
이를 해결할 수 있는 것은 string slice이다.
String Slice
String의 일부분에 대한 참조자이다.
형태는 다음과 같다.
pub fn run(){
let ss = String::from("String Slice");
let _string = &ss[0..6];
let _slice = &ss[7..11];
}
String의 참조자를 가지게 되는건 비슷하지만, 일부분에 대한 참조자를 가지고 있는 것이다.
선언된 형태를 보면 알겠지만 참조할 문자열의 "[시작인덱스..끝인덱스+1]" 형태이다.
시작과 끝부분은 요렇게도 작성 가능하다.
let ss = String::from("test");
let start_slice = &ss[..2];
let end_slice = &ss[2..];
let total = &ss[..];
이제 가장 위에서 작성했던 코드를 다시 작성해보자.
(String Slice는 &str타입으로 반환)
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[..]
}
pub fn run(){
let mut s = String::from("test");
let len = first_word(&s);
s.clear();
println!("{}", len);
}
위 코드를 실행하면 다음과 같은 오류가 발생한다.
불변 참조자를 만들었을 경우 가변 참조자를 만들 수 없다.
clear함수가 String을 비울 때, 가변 참조자를 갖기위한 시도를 하고 실패를 하게 된다. (&str은 불변참조자)
String literal은 slice이다.
여기서 s의 data type은 &str이다.
let s = "test";
이것은 바이너리의 특정 지점을 가지고 있는 Slice고 String literal이 불변인지에 대한 이유가 된다. &str은 불변참조자이다.
Parameter로써의 String Slice
위의 first_word함수를 한번 더 개선한 모습이다.
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[..]
}
pub fn run(){
//let mut s = String::from("test");
let s = "test";
let len = first_word(&s);
println!("{}", len);
}
만약 String Sliece를 argument로 바로 넘길 수 있고, 또한 String을 넘긴다면 String전체의 slice를 넘길 수 있다.
이 장의 전체 코드
//소유권을 갖지 않는 데이터타입.
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[..]
}
pub fn run(){
//let s = String::from("test");
let s = "test";
let len = first_word(&s);
//s.clear();
println!("{}", len);
}
참고 : rinthel.github.io/rust-lang-book-ko/ch04-03-slices.html
슬라이스 - The Rust Programming Language
소유권을 갖지 않는 또다른 데이터 타입은 슬라이스입니다. 슬라이스는 여러분이 컬렉션(collection) 전체가 아닌 컬렉션의 연속된 일련의 요소들을 참조할 수 있게 합니다. 여기 작은 프로그래밍
rinthel.github.io
'Rust-Language' 카테고리의 다른 글
method (0) | 2021.04.07 |
---|---|
구조체 (0) | 2021.04.07 |
참조자와 빌림 (0) | 2021.04.03 |
소유권(Ownership) (0) | 2021.04.02 |
제어문 (0) | 2021.03.30 |