|
1 | 1 | % Unsized Types
|
2 | 2 |
|
3 |
| -Coming Soon! |
| 3 | +Most types have a particular size, in bytes, that is knowable at compile time. |
| 4 | +For example, an `i32` is thirty-two bits big, or four bytes. However, there are |
| 5 | +some types which are useful to express, but do not have a defined size. These are |
| 6 | +called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This type |
| 7 | +represents a certain number of `T` in sequence. But we don’t know how many |
| 8 | +there are, so the size is not known. |
| 9 | + |
| 10 | +Rust understands a few of these types, but they have some restrictions. There |
| 11 | +are three: |
| 12 | + |
| 13 | +1. We can only manipulate an instance of an unsized type via a pointer. An |
| 14 | + `&[T]` works just fine, but a `[T]` does not. |
| 15 | +2. Variables and arguments cannot have dynamically sized types. |
| 16 | +3. Only the last field in a `struct` may have a dynamically sized type; the |
| 17 | + other fields must not. Enum variants must not have dynamically sized types as |
| 18 | + data. |
| 19 | + |
| 20 | +So why bother? Well, because `[T]` can only be used behind a pointer, if we |
| 21 | +didn’t have language support for unsized types, it would be impossible to write |
| 22 | +this: |
| 23 | + |
| 24 | +```rust,ignore |
| 25 | +impl Foo for str { |
| 26 | +``` |
| 27 | + |
| 28 | +or |
| 29 | + |
| 30 | +```rust,ignore |
| 31 | +impl<T> Foo for [T] { |
| 32 | +``` |
| 33 | + |
| 34 | +Instead, you would have to write: |
| 35 | + |
| 36 | +```rust,ignore |
| 37 | +impl Foo for &str { |
| 38 | +``` |
| 39 | + |
| 40 | +Meaning, this implementation would only work for [references][ref], and not |
| 41 | +other types of pointers. With this `impl`, all pointers, including (at some |
| 42 | +point, there are some bugs to fix first) user-defined custom smart pointers, |
| 43 | +can use this `impl`. |
| 44 | + |
| 45 | +# ?Sized |
| 46 | + |
| 47 | +If you want to write a function that accepts a dynamically sized type, you |
| 48 | +can use the special bound, `?Sized`: |
| 49 | + |
| 50 | +```rust |
| 51 | +struct Foo<T: ?Sized> { |
| 52 | + f: T, |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +This `?`, read as “T may be `Sized`”, means that this bound is special: it |
| 57 | +lets us match more kinds, not less. It’s almost like every `T` implicitly has |
| 58 | +`T: Sized`, and the `?` undoes this default. |
0 commit comments