How do I use the box keyword in pattern matching?
Asked Answered
C

2

10

This code is shown in The Rust Programming Language:

#![feature(box_syntax, box_patterns)]

fn main() {
    let b = Some(box 5);
    match b {
        Some(box n) if n < 0 => {
            println!("Box contains negative number {}", n);
        }
        Some(box n) if n >= 0 => {
            println!("Box contains non-negative number {}", n);
        }
        None => {
            println!("No box");
        }
        _ => unreachable!(),
    }
}

But when I run it, the following error occurs:

error[E0554]: #[feature] may not be used on the stable release channel

I also tried

fn main() {
    let b = Some(box 5);
}
error: box expression syntax is experimental; 

Is it because my version of Rust is not the latest? How I can get the content in Box::new()? I tried

fn main() {
    let b = Some(Box::new(5));
    match b {
        Some(Box::new(y)) => print!("{:?}", y), 

        _ => print!("{:?}", 1),
    }
}
error[E0164]: `Box::new` does not name a tuple variant or a tuple struct
--> main.rs:6:14
  |
6 |         Some(Box::new(y)) => print!("{:?}", y), 
  |              ^^^^^^^^^^^ not a tuple variant or struct
Capitulate answered 11/2, 2017 at 14:50 Comment(2)
You read through the entire Rust Book, got to chapter 6.8 about box syntax, but didn't read the intro to chapter 6 entitled Nightly Rust that describes the first 2/3 of your question?Pubilis
@S U are right. I just skipped to the syntax of Rust. It seems that the intro is also important...Capitulate
M
14

You are using a #[feature] and those can only be used with a nightly Rust compiler. I don't think it is currently possible to match against a Box in stable Rust, but nightly allows the following way of doing it (like you attempted in the beginning):

#![feature(box_patterns)]

fn main() {
    let b = Some(Box::new(5));
    match b {
        Some(box y) => print!("{:?}", y),
        _ => print!("{:?}", 1),
    }
}
Moxa answered 11/2, 2017 at 15:5 Comment(2)
Ah ha. So if I don't use match, is there any other way to get the content in the Box?Capitulate
Yes; you just need to dereference it with an asterisk, e.g. assert_eq!(*Box::new(1), 1);Moxa
R
5

Rust has three release channels: stable, beta, and nightly.

Stable is the main release, and the Rust developers take care to make sure that features and updates made to the stable channel are, well, stable. That means that they're fully implemented and safe to use, but most importantly, when the Rust developers add a feature to stable, it means that they are making a commitment to backwards compatibility.

The backwards compatibility commitment is important because it means that developers can start using stable features in libraries without having to worry about whether they'll have to rewrite large parts of their library from scratch when the language is updated.

There are other features available in Rust, for example the box syntax, which aren't completely finalized yet. Many of these have partial or nearly complete implementations, but their exact syntax and implementation is still subject to change. Because these features are not considered stable, they are potentially subject to backwards-incompatible changes which could break your existing code if you depend on them.

For example, there are, or were, two proposals for syntax for what's called "placement new" (avoiding the need to first allocate on the stack then copy to the heap):

in PLACE { BLOCK }
PLACE <- EXPR

When placement new reaches stable, only one syntax will be available. However, during development, the Rust team may experiment with multiple ways of doing things, and change them as they see fit. Anyone using unstable features will have to update their code any time the compiler or language APIs change.

But sometimes people want to take that risk, and make use of features that aren't available in the stable release yet, knowing they may have their code broken by future releases.

For that there is the nightly release. This is a version of the compiler that is built with unstable features and APIs enabled. If you use the nightly release, you can use box syntax and a variety of other features not deemed ready for stable release.

Probably the easiest way to get a nightly build, and to switch between nightly and stable releases is to install rust using rustup.

Rustup makes it easy to install Rust compilers targeting different platforms, and to switch between stable, nightly, and beta releases.

Remunerative answered 11/2, 2017 at 15:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.