Rust has a good language feature supporting the compile-time evaluation of function.
It is const fn
.
At the time this post is written this feature is not in a state of stabilized, but you can use it using Nightly Rust compiler.
An example of const fn
is below.
#![feature(const_fn)]
const fn to_celsius(x: i32) -> i32 {
((x as f64 - 32.0) / 1.8) as i32
}
const FAHR_75: i32 = 75;
const CELS_F75: i32 = to_celsius(FAHR_75);
fn main() {
println!("75F equals {}C", CELS_F75);
}
As we can imagine, const fn
functions run at compile-time, so there are no run-time costs to use this feature. It is similar to constexpr
functions in C++.
If we need to define some constants which have complex expressions, it is a good chance to use it.
If we are using fixed-length objects like arrays and want to calculate the value related to the length of the array, it is also a good chance to use const fn
because Rust
compiler can determine value of the elements of an expression.
To use const fn
, the function must be called in constants contexts and constant arguments. In other words, the values of all elements of the expressions or statements must be determined at compile-time.
It is different from macros
.
macros
just replace the text at compile-time, it does not calculate expression but produces some code from meta-code. But const fn
calculates some expressions.
Let’s see this.
macro_rules! to_celsius (
($value:expr) => (
(($value as f64 - 32.0) / 1.8) as i32
)
);
const FAHR_75: i32 = 75;
const CELS_F75: i32 = to_celsius!(FAHR_75);
fn main() {
println!("75F equals {}C", CELS_F75);
}
The behavior of the two codes is the same. But the steps to make the results differ.
When the macro is used, the Rust compiler produces this code first.
const FAHR_75: i32 = 75;
const CELS_F75: i32 = ((FAHR_75 as f64 - 32.0) / 1.8) as i32;
fn main() {
println!("75F equals {}C", CELS_F75);
}
Then Rust compiler tries to calculate the CELS_F75. In this case, the running costs of the above two programs are the same. But as you can see, using const fn
makes simpler and prettier code.
Thanks for reading.