Hacker News new | ask | show | jobs
by someone13 4024 days ago
To elaborate a bit on the sibling comment here, Rust makes things a bit more explicit than Go does. A Go interface type is actually a pointer (of sorts), since you don't generally want to store things of different types and sizes in a single array. For example, if you have:

    type StructOne struct {
        field uint32
    }
    
    type StructTwo struct {
        field uint64
    }
It's pretty clear that these structures are of different size. Now, if both of these structures implement the "Foo" interface, we can't simply make an array like []Foo, since we'd have no practical method to index into the array. Go solves this by making []Foo actually be an array of pointers.

However, Rust's philosophy is, AFAIK, "be explicit about the cost you pay". So, if you want to make an "array of things that implement Foo", you need to explicitly put the "things" behind a pointer, or a Box<>. So, you get:

    struct MyStruct {
        arr: Vec<Box<Foo>>,
    }
Which makes it explicit that you're storing a "list of pointers to things that implement Foo". Of course, the nice part is that you can use generic syntax to make an array that doesn't use pointers, like so:

    struct MyStruct2<T: Foo> {
        arr: Vec<T>,
    }
In the above, you can only store items of a single type in the `arr` field, and the generics constrain that to be only types `T` that implement Foo. The upside is, however, that you don't have any pointer indirection (and the compiler monomorphizes - i.e. generates new code for each generic implementation), so your code is probably faster / easier for LLVM to optimize.