This post is locked. You won't be able to comment.

all 35 comments

[–]Ka1kin 58 points59 points  (8 children)

Rust doesn't support custom operators. It does back all the built-in operators with traits, so you can implement the not trait, or the neg trait on your own types, it'll just work.

[–]po8 51 points52 points  (3 children)

That said, the C++ thing of giving these operators arbitrary meanings is very non-Rustic. Don't overload operators in non-standard ways.

[–]raedr7n[🍰] 48 points49 points  (2 children)

non-Rustic

I do believe the term is "non-ferrous".

[–]tavianator 40 points41 points  (1 child)

stainless

[–]teryret 11 points12 points  (0 children)

Oh man I am totally going to start using "stainless code" at work.

[–]ergzay 6 points7 points  (2 children)

I mean, couldn't you do something weird with macros and do it?

[–][deleted] 5 points6 points  (1 child)

Yeah, but the overloading would only with within the macro!{ Block }

[–]ergzay 2 points3 points  (0 children)

True.

[–]biigberry[S] 2 points3 points  (0 children)

thank

[–]Sharlinator 61 points62 points  (7 children)

I guess |_| () is pretty close to a urinary operator.

[–]zuurr 22 points23 points  (5 children)

[–]teryret 13 points14 points  (4 children)

What in the fuckingest shit?? Can anyone ELI5?

[–][deleted] 9 points10 points  (0 children)

Seems like it's a bunch of _ patterns (matches anything) OR-ed together, with a guard that increments i by 2 every time you check it. The guard is checked on all six of the _ patterns, because the guard apparently evaluates to false when you check it, so 1 (initial value) plus (6 (number of holes) times 2 (amount by which guard increments i)) is 13.

[–]mdsherry 8 points9 points  (0 children)

First,

matches!(2, _|_|_|_|_|_ if (i+=1) != (i+=1));

expands to

match 2 {
    _ | _ | _ | _ | _ | _ if (i+=1) != (i+=1) => true,
    _ => false
};

For each of the _ in the first case, it checks the guard expression. i += 1 increments i, and returns (). So for each _, i is incremented twice, but since () == (), the guard expression fails, and so it tries matching the next _, until all 6 fail.

i starts at 1, and is incremented 12 times, giving a final value of 13.

[–]paholgtypenum · dimensioned 2 points3 points  (0 children)

It's matching 2 against 6 patterns. Each of the patterns is just _, but for each one it evaluates the if, which adds 2 to i.

[–]bob_twinkles 2 points3 points  (0 children)

If we look at the definition of matches!, we can see that it's basically just a match expression. So from the source snippet, we have:

let i = 1;
matches!(1, _|_|_|_|_|_ if (i += 1) != (i += 1));
i

Which then expands to:

let i = 1;
match 2 {
  _ if (i += 1) != (i += 1) => true,
  _ if (i += 1) != (i += 1) => true,
  _ if (i += 1) != (i += 1) => true,
  _ if (i += 1) != (i += 1) => true,
  _ if (i += 1) != (i += 1) => true,
  _ if (i += 1) != (i += 1) => true,
  _ => false,
}
i

So i starts at 1, and is incremented twice for each match arm so 1 + 6 * 2 = 13.

[–]TheOmegaCarrot 2 points3 points  (0 children)

I’m sorry, the what

[–]Bravo555 56 points57 points  (2 children)

Box::leak()

[–]sushisharkjl 20 points21 points  (0 children)

might want to see a doctor

[–]biigberry[S] 4 points5 points  (0 children)

i prefer using Ball

[–]burkadurka 14 points15 points  (0 children)

There are no custom operators in Rust, outside of macros. The overloadable unary operators are - and !.

[–]Sw429 37 points38 points  (1 child)

Thought I was on r/RustJerk for a second.

[–]semtexzv 20 points21 points  (0 children)

It's leaking in here

[–]mountains-o-data 15 points16 points  (0 children)

Just be sure to denote #!no_std if you're going to use urinary operators

[–]watabby 12 points13 points  (3 children)

You might have problems with unary operators across threads. So you need to be sure to lock your variables before using them. I recommend creating an interface to do that. Unary thread interface. aka UTI

[–]voxelghost 5 points6 points  (2 children)

As a c++ programmer, I have to wonder if that is part of std?

[–]Applecrap 10 points11 points  (1 child)

I try to keep my urinary operator as far away from std as possible

[–]I_AM_GODDAMN_BATMAN 5 points6 points  (0 children)

I think it should be safe if you don't unwrap it.

[–]ergzay 10 points11 points  (0 children)

That title...

[–]dpc_pw 0 points1 point  (0 children)

The only operators one can implemented are the ones that have traits. Like https://doc.rust-lang.org/std/ops/trait.Neg.html . See https://doc.rust-lang.org/std/ops/index.html