1

I want to write a small factorial library. Please look at the code inside the main module of the library:

pub fn results() -> const [i8; 6] { [
      1,
      1,
      2,
      6,
     24,
    120,
    //720 is too large for i8.
] }

pub fn results() -> const [i32; 13] { [
              1,
              1,
              2,
              6,
             24,
            120,
            720,
          5_040,
         40_320,
        362_880,
      3_628_800,
     39_916_800,
    479_001_600,
    //6_227_020_800 is too large for i32.
] }

It gives me this error for the return type of the first function:

error: expected type, found keyword `const`
 --> src/main.rs:1:21
  |
1 | pub fn results() -> const [i8; 6] { [
  |                     ^^^^^

The goal is to get an array of all possible factorial values at compile time.

Timon Paßlick
  • 193
  • 1
  • 11

2 Answers2

5

In case you want to return a immutable variable, you have to omit the const. In Rust, variables are immutable by default. This is similar to declaring everything const in C++. You can opt out of this with introducing mutability.

pub fn results() -> [i8; 6] {
    unimplemented!()
}

For further information see the official book:

By default variables are immutable. This is one of many nudges Rust gives you to write your code in a way that takes advantage of the safety and easy concurrency that Rust offers. However, you still have the option to make your variables mutable. Let’s explore how and why Rust encourages you to favor immutability and why sometimes you might want to opt out.

If you want to make your function evaluated at compile time, you need the const_fn feature, which is still under development. However, it's stable enough to do what you want:

pub const fn results() -> [i8; 6] {
    [1, 1, 2, 6, 24, 120] // 720 is too large for i8.
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Tim Diekmann
  • 7,755
  • 11
  • 41
  • 69
5

get an array of all possible factorial values at compile time

Just declare constant values:

pub const RESULTS_I8: [i8; 6] = [1, 1, 2, 6, 24, 120];

pub const RESULTS_I32: [i32; 13] = [
    1,
    1,
    2,
    6,
    24,
    120,
    720,
    5_040,
    40_320,
    362_880,
    3_628_800,
    39_916_800,
    479_001_600,
];

There's no reason to involve a function at all because there's no computation needed!

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I wanted to use functions so that the type could maybe be deduced. But I guess I'll do it like that until `const fn` becomes stable. – Timon Paßlick Jul 02 '18 at 18:48
  • 1
    @TimonPaßlick *the type could maybe be deduced* —what type deduction? There's exactly as many explicit types in this answer as your proposed code. [Rust does not have inference of top-level items](https://stackoverflow.com/q/31609137/155423). – Shepmaster Jul 02 '18 at 18:55
  • Thank you, I did not know that. I'm used to the C++ type system. – Timon Paßlick Jul 02 '18 at 19:06