러스트 슬라이스 타입에 대해 공부한 내용을 정리합니다.
이전 글에서는 러스트만의 고유한 참조 방식에 대해서 살펴보았다. 러스트의 참조 방식은 데이터 경합을 유발할 수 있는 경우를 제외한 제한된 허용 하에서 사용할 수 있었다. 이번 글에서는 이런 러스트의 특성을 잘 나타내는 슬라이스 타입에 대해 정리할 것이다.
첫 번째 문자를 도출하기
어떤 문장에서 첫 번째 문자를 도출하고 싶다. 이런 경우 러스트에서 어떻게 코드를 만들 수 있을까? 아래의 코드를 살펴보자.
1 | fn main(){ |
위 코드는 “Hello world!”에서 첫 번째 단어의 글자 수를 반환해주는 함수이다. first_word()
를 자세히 살펴보자.
먼저 first_word()
는 문자열을 받아 이를 byte로 변환한다. 이렇게 변환하면 변수 bytes
는 [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33] 배열로 저장된다. 이를 for
문으로 통해 인덱스와 함께 하나씩 살펴보면서 공백(32)과 동일한 수가 있다면 인덱스인 i
를 반환한다.
위 함수는 그럴 듯 해보인다. 하지만 문자열 변수 sen
가 변경되거나 사라져도 num
값은 계속 유지된다. 위 코드에서 sen.clear()
를 통해 변수 sen
을 제거하였음에도 num
은 사라지지 않는다. 이런 변수들의 독립성은 추후 컴파일단에서 잡히지 않는 버그가 될 수 있다. 나중에 변수 sen
이 변경된 상태에서 num
값을 사용하여 첫 번째 단어를 추출해도 프로그램 상 어떤 오류도 발생하지 않기 때문이다.
따라서 변수 sen
이 변경되거나 사라지면 에러가 도출되는 함수를 만들고 싶다. 그럴 때 러스트의 슬라이스 타입을 사용할 수 있다.
슬라이스 타입이란
슬라이스(Slice) 타입은 소유권을 갖지 않으며, 문자열의 일부를 참조하는 방식이다. 위 예시에서 사용된 문자열 변수 sen
을 통해 예시를 살펴보자.
1 | fn main(){ |
위 코드는 변수 sen
의 값인 “Hello world!”에서 변수 first
가 인덱스 0부터 5까지의 문자열을 참조로 가져오며, 변수 second
는 인덱스 5에서부터 끝까지의 문자열을 참조로 가져온다. 한번 더 강조하지만 슬라이스 타입은 참조이기 때문에 변수 sen
의 값이 변경된다면 first
, second
를 도출하는 데 문제가 발생한다.
1 | fn main(){ |
위 코드는 전의 코드와 다르게 에러를 반환한다. 차이는 sen.clear();
이것 딱 하나이다. 에러를 자세히 살펴보면 슬라이스 타입에 이미 &로 참조가 되었기 때문에 변수 sen
을 변경할 수 없다고 설명한다. 이처럼 슬라이스 타입을 사용한다면 앞서 봤던 오류를 해결할 수 있다.
슬라이스를 사용하여 첫 번째 문자를 도출하기
이제 배운 슬라이스 타입을 사용하여 첫 번째 문자를 도출해보자. 코드는 아래와 같다.
1 | fn main(){ |
위 코드는 전반적인 논리는 앞에서 설명한 바와 동일하다. 다만 발견한 첫 번째 문자의 마지막 인덱스를 사용하여 슬라이스 타입으로 첫 번째 단어를 도출한다. 이렇게 코드를 변경하면 변수 sen
가 변경되었을 시에도 이전 문장의 첫 번째 단어를 가져올 수 있다.
1 | fn main(){ |
위 코드의 결과는 다음과 같다.
1 | Hello |