Vec<T> of length 1 to a T?

            assert!(props.len() == 1);
            let mut props = props;
            let t = props.pop().unwrap();

Here props: Vec<T>. I find this whole dance a bit inelegant. I can't get props[0] since that appears to return a ref. I'd prefer to just do props.singleton().unwrap() but that doesn't exist.

If you have a Vec, is there an idiomatic way to: convert it to T is there is only one element, and panic otherwise ?

It does not. Here's the playground demonstrating as much: Rust Playground

let [t] = <[_; 1]>::try_from(props).unwrap();

Or:

let [t]: [_; 1] = props.try_into().unwrap();

Unfortunately, it seems you need some kind of type annotation here or else inference falls over.

4 Likes

maybe something like that

    let v = vec![1];

    let value = match &v[..] {
        [unique] => unique,
        [_, _, ..] => panic!("error more than one value"),
        [] => panic!("error empty vector"),
    };

That's because it's desugared to a deferenced reference. Thus, you can't use it to move the value out, which is what the OP will seems to want per their solution.

1 Like

With itertools, you can .into_iter().exactly_one().unwrap().

4 Likes

Here's the general issue there: Irrefutable slice patterns should be inferred as arrays of that length · Issue #76342 · rust-lang/rust · GitHub

Though even if that were fixed it's possible that the .try_into().unwrap() would still need annotations -- I forget if you can get a &[T] from that, which would then be ambiguous.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.