[rust-dev] Questions from a newcomer

Corey Richardson corey at octayn.net
Sun Jan 12 09:16:09 PST 2014


Hi Abraham,

> * Is there any built-in way to iterate over all values of a C-like enum?
> It's not hard to define an iterator method that implements this for any
> given type, but it's tedious boilerplate that seems better left to the
> compiler.
>

Not really. What is your usecase? One boilerplate-avoiding workaround
is to use FromPrimitive[1] and put `#[deriving(FromPrimitive)]` on
your enum. Then, to iterate over the valid discriminants, you can use:

range(0, std::uint::max_value).filter_map(|x|
FromPrimitive::from_uint(x).map(|y| y as uint))

Note that this iterates over the entire range of uint. This is
required for an enum like:

enum WhatAPain {
    A,
    B = 42,
    C = 12312455
}

Needless to say this is not going to perform well. You can substitute
the variant whose discriminant is the largest to make it cheaper:

range(0, C as uint).filter_map(|x| FromPrimitive::from_uint(x).map(|y|
y as uint))

> * Is it possible to express "if a type implements trait A, here is a
> default implementation of trait B"?  I tried the obvious way ("impl<T:
> TraitA> TraitB for T"), but it looks like the rust compiler can't
> disambiguate between that impl and type-specific impls.
>

You are doing it correctly. There is an issue open about this:
https://github.com/mozilla/rust/issues/10601

> * Why does the do-notation require a function that takes a proc()?  Given
> that || is the recommended type for HOFs it seems like it would be much more
> convenient if it worked with functions expecting a proc() or a ||.
>

`do` previously applied to any closure type but that was removed
because the meaning of `do` can change wildly depending on what you
apply it to. In particular, using the old syntax, do applied to a
`fn(~fn())` will have an allocation, whereas `fn(&fn())` will not. To
make such costs obvious, `do` no longer works with `&fn()` (now
written `||`). `proc()` corresponds to `~once fn()`, that is, a
closure which may be called once and whose environment is allocated on
the heap. The advantage of this is that it allows for moving values
into the body of `do`.

[1]: http://static.rust-lang.org/doc/0.9/std/num/trait.FromPrimitive.html


More information about the Rust-dev mailing list