1

I want to write a simple Rust function that takes an u64 modulo an u8, and returns an u8:

fn bucket(value: u64, number_of_buckets: u8) -> u8 {
    value % number_of_buckets
}

However, this does not compile because of mismatching types:

error[E0308]: mismatched types
 --> src/lib.rs:2:13
  |
2 |     value % number_of_buckets
  |             ^^^^^^^^^^^^^^^^^ expected u64, found u8

error[E0308]: mismatched types
 --> src/lib.rs:2:5
  |
1 | fn bucket(value: u64, number_of_buckets: u8) -> u8 {
  |                                                 -- expected `u8` because of return type
2 |     value % number_of_buckets
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found u64
help: you can convert an `u64` to `u8` and panic if the converted value wouldn't fit
  |
2 |     (value % number_of_buckets).try_into().unwrap()
  |

error[E0277]: cannot mod `u64` by `u8`
 --> src/lib.rs:2:11
  |
2 |     value % number_of_buckets
  |           ^ no implementation for `u64 % u8`
  |
  = help: the trait `std::ops::Rem<u8>` is not implemented for `u64`

To fix it, I have to write this very ugly code:

use std::convert::TryInto;

fn bucket(value: u64, number_of_buckets: u8) -> u8 {
    (value % number_of_buckets as u64).try_into().unwrap()
}

Is there no simpler way to do this, without two explicit type conversions and two function calls? The fact that I have two write so much code for something so simple makes me suspect I am missing something obvious.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Anders
  • 8,307
  • 9
  • 56
  • 88

0 Answers0