These are chat archives for rust-lang/rust

2nd
May 2019
Kris
@VersBinarii
May 02 08:43 UTC
Hello, is there a way to destructure a struct like so:
pub struct MyStruct {
    pub field1: String,
    pub field2: Option<String>,
    pub field3: Option<String>,
    pub field4: Option<String>,
    pub filed5: Option<String>,
}

let thestruct = MyStruct::new();

match thestruct{
    MyStruct{
        field1,
        filed2: Some(x)=> println!("{}", x)
    },
    MyStruct{
        field1,
        ..
        filed4: Some(y)=> println!("{}", y)
        ..
    },
    …
}
Denis Lisov
@tanriol
May 02 08:45 UTC
Do you want only one case to be executed or more than one?
Kris
@VersBinarii
May 02 08:46 UTC
more then one
there will be handler for most conbinations of fields
Denis Lisov
@tanriol
May 02 08:50 UTC
If you needed only one case to be executed (specifically, the first one matching), it would look like
    match thestruct {
        MyStruct { field2: Some(x), .. } => println!("{}", x),
        MyStruct { field4: Some(y), .. } => println!("{}", y),
        _ => {}
    }
If you need multiple, you need to have multiple match or if let statements
    if let MyStruct { field2: Some(x), .. } = &thestruct {
        println!("{}", x)
    }
    if let MyStruct { field4: Some(y), .. } = &thestruct {
        println!("{}", y)
    }
Kris
@VersBinarii
May 02 08:52 UTC
Yes, i’m familiar with that one but in my case there is always going to be the first and some other field.
ok, thank you. I’ll see if i can rewrite this with if let
Kris
@VersBinarii
May 02 09:28 UTC
Actually this works:
match thestruct {
    MyStruct{
        field1,
        field2: Some(x)=> println!("{}", x)
    },
    MyStruct{
        field1,
        field3: Some(y)=> println!("{}", y)
        ..
    },
    MyStruct{
        field1,
        field4: Some(y)=> println!("{}", y)
        ..
    },
    …
}
Denis Lisov
@tanriol
May 02 10:03 UTC
I'm seeing errors for the code you show (and they're rather expected - AFAIK, there's no syntax with action directly inside pattern).
Kris
@VersBinarii
May 02 10:13 UTC
Sorry its a copy paste error
Should be like that:
 match thestruct {
        MyStruct {
            field1,
            field3: Some(x),
            ..
        } => format!(“{}”, x),
        MyStruct {
            field1,
            field2: Some(x),
            ..
        } => format!(“{}”, x),
Denis Lisov
@tanriol
May 02 10:18 UTC
Note that if both field2 and field3 contain Some(_), only the first message will be generated. If that's what you need, everything's fine :-)
Kris
@VersBinarii
May 02 10:22 UTC
Yes, i just witnessed that this is the case. Thanks for confirming it :)
Ichoran
@Ichoran
May 02 17:24 UTC
Is there a canonical way to keep a circular index into a fixed-length array known to the compiler to be in-range?
Ingvar Stepanyan
@RReverser
May 02 17:26 UTC
@Ichoran Can you elaborate?
Ichoran
@Ichoran
May 02 17:26 UTC

If you do something like

let mut data = [0; 5];
let mut i = 0;
while something() {
    data[i] = whatever();
    i = if i < 4 { i + 1 } else { 0 };
}

it would be nice to know that the compiler understands that you can't get out of bounds and doesn't insert any checks.

Ichoran
@Ichoran
May 02 17:34 UTC
I checked something like this on godbolt and it does insert the checks, unfortunately.
Ingvar Stepanyan
@RReverser
May 02 17:46 UTC
can you provide a link?
then it's easier to understand the particular issue
Ichoran
@Ichoran
May 02 18:02 UTC
@RReverser - My mistake; I'd left off the -O flag on godbolt. So it does work (presumably), but I still don't know how to know whether it will work aside from asking godbolt.
Ingvar Stepanyan
@RReverser
May 02 18:04 UTC
I'd say yeah, either ask godbolt or just don't worry about it until you find it to be an actual problem.
Ichoran
@Ichoran
May 02 18:05 UTC
That is what I'll do in the absence of any clear understanding; I just like to know how to get these things to work in advance so that in performance-critical areas I can start off doing the right thing rather than doing whatever and then painfully going back with decompilation and microbenchmarking and stuff until the problem goes away.
In my current case I don't really care very much, but I'm trying to make this a learning experience also so I can have a better chance of writing really fast code when I need to. (I work with large data sets on my laptop, so it comes up pretty often.)
Ingvar Stepanyan
@RReverser
May 02 18:06 UTC
Then yeah, microbenchmark it once, check on godbolt, wrap into a function/crate and reuse everywhere else :)
It's not coming up too often, and normally you'd use iterators anyway (which don't have a problem in the first place).
Ichoran
@Ichoran
May 02 18:07 UTC
Maybe the moral of the story is that godbolt is awesome :) I tend to write a lot of little performance-critical functions with hopefully tight loops. But I guess it's not too hard to ask every time.
Oh I do use iterators; the point with the fixed-sized circular buffer is to get some history while using iterators "normally".
Ingvar Stepanyan
@RReverser
May 02 18:07 UTC
Actually, even here you should be able to use .cycle() instead.
Ichoran
@Ichoran
May 02 18:08 UTC
Oh? I hadn't noticed that. What is it?
wraps around any iterator
into infinite loop
seems exactly what you're doing
Ichoran
@Ichoran
May 02 18:09 UTC
Ah, no, not really, unfortunately. That's a handy function to know, though.
Ingvar Stepanyan
@RReverser
May 02 18:10 UTC
Hmm how is it different?
Ichoran
@Ichoran
May 02 18:10 UTC
In the current case (it varies a lot, but as an example) I'm calculating a running median.
Ingvar Stepanyan
@RReverser
May 02 18:10 UTC
Ah I was talking about your specific godbolt example
Ichoran
@Ichoran
May 02 18:11 UTC
Oh, yeah. The example is silly; it's just hopefully tricky enough to get the assembly to be representative :)
It's got a closed-form solution. Mathematica would probably find it.