Discussion:
[rust-dev] std::rand::Rng
Petr Novotnik
2014-09-16 19:41:30 UTC
Permalink
Hello list,
use std::rand::{Rng, task_rng};
fn main() {
let rng = &mut task_rng();
print_numbers(rng);
}
fn print_numbers(r: &mut Rng) {
for _ in range(0u, 10) {
println!("{}", r.gen::<uint>());
}
}
rustc random.rs
random.rs:10:24: 10:39 error: cannot call a generic method through an object [E0039]
random.rs:10 println!("{}", r.gen::<uint>());
^~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
random.rs:10:9: 10:41 note: expansion site
error: aborting due to previous error
I think the reason for the error message is because the compiler cannot
statically dispatch the call. Correct?

If so, I wonder what the motivation is for having generic methods in
traits which themselves are not generified. If I understand it
correctly, there's no chance invoking such a generic method through a
trait type.

Pete.
Petr Novotnik
2014-09-16 19:53:37 UTC
Permalink
Is it to allow the following pattern?
fn print_numbers<R: Rng> (r: &mut R) {
for _ in range(0u, 10) {
println!("{}", r.gen::<uint>());
}
}
Pete.
Evan Davis
2014-09-17 21:26:58 UTC
Permalink
The problem is that you're trying to use a trait as a type. This code works
for me

```
use std::rand::{Rng, task_rng};

fn main() {
let rng = &mut task_rng();
print_numbers(rng);
}

fn print_numbers<T:Rng>(r: &mut T) {
for _ in range(0u, 10) {
println!("{}", r.gen::<uint>());
}
}
```

-Evan Davis

On Tue, Sep 16, 2014 at 12:53 PM, Petr Novotnik <pnovotnik at googlemail.com>
Post by Petr Novotnik
Is it to allow the following pattern?
fn print_numbers<R: Rng> (r: &mut R) {
for _ in range(0u, 10) {
println!("{}", r.gen::<uint>());
}
}
Pete.
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140917/9efa1b2c/attachment.html>
Sean McArthur
2014-09-17 21:33:11 UTC
Permalink
Post by Evan Davis
The problem is that you're trying to use a trait as a type.
That shouldn't be a problem. You can use a `&mut Trait`, and you'll get
dynamic dispatch.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140917/269f0b4c/attachment.html>
Felix S. Klock II
2014-09-18 08:42:10 UTC
Permalink
Post by Evan Davis
The problem is that you're trying to use a trait as a type.
That shouldn't be a problem. You can use a `&mut Trait`, and you'll get dynamic dispatch.
You cannot mix dynamic dispatch with generic methods. (This is because we implement generic methods by monomorphization, i.e. by creating separate copies of the implementation for each instantiation -- but with dynamic dispatch, we do not know a priori what all of the calls to the method will be.)

I would link a relevant portion of the Rust manual here, but I cannot actually find documentation of this restriction.

----
Post by Evan Davis
fn print_numbers(r: &mut Rng) {
for _ in range(0u, 10) {
println!("{}", r.gen::<uint>());
}
}
fn print_numbers<R: Rng> (r: &mut R) {
for _ in range(0u, 10) {
println!("{}", r.gen::<uint>());
}
}
where the trait is now being used as a bound on a generic type, rather than as the basis of an object type.

Cheers,
-Felix

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140918/710c214b/attachment.html>
Loading...