Josh Vander Hook
Josh Vander Hook

Reputation: 286

How can I import two types with the same name from different modules?

The rand_distr::Poisson struct provides some useful sampling code, whereas the statrs::distribution::Poisson struct provides other things like pmf() and so on.

I'd like to use both; is this possible?

use rand_distr::Poisson;
use statrs::distribution::Poisson;

has an error in vscode:

Error: the name `Poisson` is defined multiple times
label: previous import of the type `Poisson` here
note: `Poisson` must be defined only once in the type namespace of this module
label: previous import of the type `Poisson` here
warning: unused import: `rand_distr::Poisson`

And in particular cargo reports

error[E0252]: the name `Poisson` is defined multiple times
 --> src/main.rs:3:37
  |
1 | use rand_distr::{Poisson, Distribution};
  |                  ------- previous import of the type `Poisson` here
2 | use rand::distributions::Distribution;
3 | use statrs::distribution::{Discrete,Poisson};// as statrs_Poisson};
  |                                     ^^^^^^^ `Poisson` reimported here

All instances of Poisson in the code are now considered statrs::distribution::Poisson, even if I attempt to 'fully namespace them'.

let p_one = rand_distr::Poisson::new(rate_one_baseline).unwrap();
let v = p_one.sample(&mut rand::thread_rng());

fails, claiming there's no sample method.

Solution

The answer below is the correct one. This example was complicated by two overlapping imports, so I had to rename two use.

//broke:
use rand_distr::{Poisson, Distribution};
use rand::distributions::Distribution; //provides pmf()
use statrs::distribution::{Discrete,Poisson};// implements Distribution
//ok:
use rand_distr::{Poisson, Distribution};
use rand::distributions::Distribution as _;
use statrs::distribution::{Discrete,Poisson as statrs_Poisson};

Working example

use rand_distr::{Poisson, Distribution};
use rand::distributions::Distribution as _;
use statrs::distribution::{Discrete,Poisson as statrs_Poisson};
fn main() {

    let poi = rand_distr::Poisson::new(2.0).unwrap();
    let poi_statrs = statrs_Poisson::new(2.0).unwrap();
   
    //   rand_distr
    //yep:
    let x1 = poi.sample(&mut rand::thread_rng());
    //nope:
    //let _y1 = poi.pmf(0);
    println!("poi  1:{}", x1);

    //   statrs
    //yep:
    let x2 = poi_statrs.pmf(0);
    println!("poi  2:{}", x2);
    //nope:
    //let _y2 = poi_statrs.sample(&mut rand::thread_rng() ); 
}

Upvotes: 3

Views: 3164

Answers (1)

asmmo
asmmo

Reputation: 7100

Use a different name:

use rand_distr::Poisson;
use statrs::distribution::Poisson as statrs_Poisson;

Then when you want to use the second one (imported from statrs), use statrs_Poisson, not Poisson, like statrs_Poisson::pmf().

Upvotes: 6

Related Questions