32

How can I port this C++ code to Rust:

auto sgnR = (R >= 0.) ? 1. : -1.;

I have seen some examples with the match keyword, but I don't understand how it works.

Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
Stepan Yakovenko
  • 7,404
  • 22
  • 105
  • 187
  • 2
    https://github.com/rust-lang/rfcs/issues/1362 – Barmar Jul 14 '17 at 00:04
  • 3
    Google "rust ternary operator" and you'll find a bunch of hits. – Barmar Jul 14 '17 at 00:04
  • @Baum This question requires understanding of both Rust and C++ so it is one of the very few questions that should have both tags. I do, however, think it should be closed for *other* reasons. – Galik Jul 14 '17 at 00:10
  • @Galik Nah, tags are for finding relevant stuff. No one with a C++ question will want to find this question, so it should not have the tag. It's not a C++ question, but solely a rust question. (Also, I don't get the "it should be closed for *other* reasons" part, that appears to pretty orthogonal to the whole tagging issue.) – Baum mit Augen Jul 14 '17 at 00:14
  • @BaummitAugen But how do you expect a pure Rust programmer to convert code from a language he doesn't understand? Some knowledge of C++ is required. If people don't want to find this question then it should rather be closed than mistagged – Galik Jul 14 '17 at 00:33
  • @Galik *"But how do you expect a pure Rust programmer to convert code from a language he doesn't understand?"* I don't expect people who don't know this syntax to answer this question at all, but that does not make this a question about C++. *"If people don't want to find this question then it should rather be closed than mistagged"* People looking for *C++* answers won't want to find it. People looking of Rust answer probably will. Thus it should be tagged [rust], but not [c++]. – Baum mit Augen Jul 14 '17 at 11:58
  • i just wanted to say that... coming from C/C++, the "match" statement is like a "super ternary" operator.... in that the ternary operator only allows to check a boolean to continue to one of two values... with match you can check a pattern against an input, and continue to many many different values. – don bright Jul 07 '18 at 20:55

2 Answers2

82

Rust does not have the ternary operator because it's not needed. Everything evaluates to some value, and if / else statements are no exception:

let r = 42.42;
let sgn_r = if r >= 0. { 1. } else { -1. };

You'll note that I've also changed your variable names to be idiomatic Rust. Identifiers use snake_case.

Do not be confused by the ? operator that Rust does have. This is called the "try operator" and is used to propagate errors.


Specifically for this code, it's likely you should use f64::signum:

let r = 42.42_f64;
let sgn_r = r.signum();
Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
8

As of Rust 1.50, you can use bool::then to accomplish the same thing:

let sgn_r = (r >= 0).then(|| 1).unwrap_or(-1);

Note that it is generally better to use a regular if/else statement for readability reasons, but bool::then is an alternative that may be nicer in certain circumstances.

Ibraheem Ahmed
  • 8,130
  • 1
  • 27
  • 37