Ternary operator

Did rust language support ternary operation ?

1 Like

You can use if as an expression directly:

let a = if x > 5 { 10 } else { 7 };
11 Likes

Note that similar use of match as an expression can be considered to be an N-ary operation, similar to if … else if … else if … else …, etc.

4 Likes

Though rust does not have ternary operator. You could also create macro to generate the if else code for you:

macro_rules! either {
    ($test:expr => $true_expr:expr; $false_expr:expr) => {
        if $test {
            $true_expr
        }
        else {
            $false_expr
        }
    }
}
// example of how to use macro
fn main() {
  let foo = 1;
  let bar = 2;
  either!(foo == bar => println!("it is true"); println!("it is false"));
  either!(foo != bar => println!("it is true"); println!("it is false"));
}
4 Likes

I wish not to see code like that. Rust is impenetrable enough already without further macro obfuscation. Why not just write out the "if...else..." the simple an obvious way?

12 Likes

… or use a match?

5 Likes

Exactly.

1 Like

so rust do not support traditional type ternary operation like in c and c++

No, it was not deemed necessary because you can use an if directly.

That's one way of looking at it, but I would rather say it just spells the same thing slightly differently than C and friends: if c { t } else { f } instead of c ? t : f.

Yes, perhaps it spells the same thing spelled lightly differently.

So why do that? Why introduce extra syntactic complexity and "noise" for no useful benefit?

Anyway, I have always hated the way use of ternary operators it C makes code jarringly harder to read.

One way to do a thing is quite enough and makes life much easier for others reading later.

1 Like

Just a nitpick: if <cond> {<then expr> } else { <else expr> } is not like a ternary operator, it is a ternary operator. The only difference is syntax.

But the main point of ternary operators was never syntax, but the fact that you could guarantee that a variable would have a value no matter the code within the branch:

int x = <cond> ? <then expr> : <else expr>;

guarantees that x has a value no matter the branches and the bodies of each (or else it fails to compile).

Whereas

int x;
if <cond> {
    ...
    x = ...;
} else {
    ...
    x = ...;
}
...
printf("%d\n", x); // <- read `x`

has still the danger of it being possible to write code within the ... so that the read x line is reached with an uninitialized x (e.g., a goto, or someone forgetting to write down the x = ... assignment in one of the branches).

So ternaries, despite their sigil syntax, make the code more robust / refactoring-proof, and this aspect of it is definitely kept by Rust's if then else ternaries. The only difference is that it no longer uses sigil syntax, as some people (I think it is the majority of people, tbh), consider such sigils to read less well than good ol' if then else.

So Rust features both the type safety of ternaries, and readability of if then else keywords :slightly_smiling_face:

10 Likes

Google Python ternary operator, and you'll find that Python syntax for the ternary operator is

<if_expr> if <cond> else <else_expr>

Compare this to Python if...else

if <cond>:
    <if_stmt>
else:
    <else_stmt>

So Rust is definitely not new in using if and else in the ternary operator instead of the ? : sigils. Python just couldn't unify them completely, since it is a statement-based language. Rust could unify them fully because Rust is an expression-based language.

1 Like

Notable point is that in Rust you can still write code like this. The only difference is the compiler rejects to compile if there is a chance to read uninit value in the end.

2 Likes

im not a connoisseur of design of programming languages, but AFIK the rust if else expression is syntactically different but semantically the same that the C ternary expression. Remember that the C if else is not an expression, is a statement and therefore cannot return values.

Some time ago I was also complaining about the fact that rust doesn't have ternary expression, but the if else archives the same and i always welcome that "something" has one way and only one way of express an intention.

4 Likes

I felt the same way when I came to rust. I think the ternary would actually make closures with implicit return a lot cleaner, but I wouldn't use them anywhere else... The issue is that I could use them elsewhere!

I think that Rust already has enough special symbols. It doesn't seem like it once you get used to them, but lifetimes are pretty daunting when you're not even used to generics.

Anyway, the ? operator was put to better use!

3 Likes

That is a very good point. It's better not to overload too many symbols with too many meanings.

3 Likes
what I usually do is
let colour:char = match tp.color {
		Color::Black => 'b',
		Color::White => 'w'
};