0

I'm trying to make a function using Rust that, given an integer, returns a value of type String.

The main problem I'm facing is creating a random character; once I can do that I can concatenate lots of these characters in a loop or something like that and then return the final string.

I've tried to find way to type cast an integer returned from the random function in the rand crate (as you can do in C++) but this does not seem to be the way to go.

What should I do?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
R0T0M0L0T0V
  • 7
  • 1
  • 4

1 Answers1

5

The Rust Cookbook shows how this can be accomplished elegantly. Copied from the link above:

use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;

fn random_string(n: usize) -> String {
    thread_rng().sample_iter(&Alphanumeric)
                .take(n)
                .collect()
}

If you wish to use a custom distribution that is not available in rand::distributions, you can implement it by following the source code for one of the distributions to see how to implement it yourself. Below is an example implementation for a distribution of some random symbols:

use rand::{Rng, seq::SliceRandom};
use rand::distributions::Distribution;

struct Symbols;

impl Distribution<char> for Symbols {
    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> char {
        *b"!@#$%^&*()[]{}:;".choose(rng).unwrap() as char
    }
}
sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • Thank you for that piece of info. I've updated the answer accordingly. Related question, why does the source code here do it the old/wrong way: https://docs.rs/rand/0.7.2/src/rand/distributions/other.rs.html#63 – sshashank124 Jan 01 '20 at 16:21
  • It appears that the justification is in the comment in the code you linked to. Note how it rejects values outside of 62 and loops. Without knowing more details, I'm hoping that they did some profiling and found that effectively inlining and simplifying the implementation of `Uniform` was more performant. – Shepmaster Jan 01 '20 at 16:26
  • Yeah, I saw the comment. That's why I chose a set size of 16 to avoid rejection sampling in the above implementation :P. Well anyways, I'm sure they had their reasons – sshashank124 Jan 01 '20 at 16:28
  • 1
    To be clear, your original code wasn't wrong, it was just very likely to lead someone down a bad path as soon as they added or removed a new character and had to deal with non-power-of-two sizes. – Shepmaster Jan 01 '20 at 16:33