Utility Traits - Sized

이정후·2023년 8월 9일
0

Rust

목록 보기
8/13
post-thumbnail

크기가 정해져 있는 값들

Sized는 Rust에서 대부분의 값들이 해당된다. u64는 8바이트 크기를 차지하고 (f32, f32, f32)튜플은 항상 12바이트의 공간을 차지한다. 크기가 항상 일정한 타입이 Sized이다.

i32, u8, f64, Enum, Struct 등 대부분의 타입들은 컴파일 시점에 크기가 알려지므로 Sized 타입이다.

Sized Trait

타입의 크기가 컴파일 시점에 정확하게 명시되어 있는지 나타낸다. Sized trait은 컴파일러에게 해당 타입이 힙에 할당될 때 필요한 공간의 크기를 미리 알려주는 역할을 한다.

모든 Sized 타입은 항상 Sized Trait을 구현하고 있다.

std::marker::Sized

Sized Trait은 개발자가 직접 구현할 수 없다. 적용이 필요한 타입에는 Rust가 스스로 구현하여 사용한다.
그러나 Sized를 쓸 수 있는 부분은 타입 변수의 Bound 부분이다.

use std::fmt::Debug;

fn print_something<T: Sized + std::fmt::Display>(value: T) {
	println!("{}", value)
}

fn main() {
    print_something("Hello, world!");
}

위 코드는 &str, i32, f64 등 다양한 값들을 출력할 수 있다. 단 컴파일 타임에 크기가 정해져 있는 값들만이다. 다만 크기가 지정되지 않은 유형은 매우 적고 제한적이기 때문에 Rust는 제네릭 유형 매개변수에 Sized를 암묵적으로 존재한다고 가정한다.

unsized

변수 자신의 값의 크기가 항상 일정치 않은 타입도 몇가지 있다. 문자열 슬라이스 str (&str이 아니다.)은 unsized이다. str은 힙에 있는 문자열 데이터에 대한 참조를 나타내기 위함덕분에 컴파일 타임에 크기를 정확하게 알려주지 않는다.

dyn도 마찬가지인데 trait 객체의 참조 대상 타입으로 사용되는 dyn은 주어진 트레이트 객체를 구현하고 있는 값을 가리키는 포인터이다. 참조 대상이 파일이 될 수도 있고, 다른 값들이 될 수 있기 때문에 그때 그때 다르다는 것이다.

unsized타입은 제약이 많기 때문에 특별한 경우가 아니라면 제네릭 타입 변수는 Sized타입으로 제한하고 사용해야 한다. 그래서 Rust에서는 암묵적 기본값으로 Sized가 채택되고 있다. 그러나 이렇게 기본값으로 제한하고 싶지 않다면 ?Sized라고 명시하여 꼭 Sized는 아니여도 된다. 고 명시해야 한다.

profile
꾸준하게

2개의 댓글

comment-user-thumbnail
2023년 8월 9일

좋은 글이네요. 공유해주셔서 감사합니다.

1개의 답글