Hacker News new | ask | show | jobs
by JoshTriplett 340 days ago
Exactly. We've talked about fixing this, but doing so without breaking this encapsulation would require being able to declare something like (syntax is illustrative only) `&mut [set1] self` and `&mut [set2] self`, where `set1` and `set2` are defined as non-overlapping sets of fields in the definition of the type. (A type with private fields could declare semantic non-overlapping subsets without actually exposing which fields those subsets consist of.)
1 comments

You could it in a more limited fashion by allowing fields of a struct to be declared "const", which would have similar semantics to Java's final. If you add the ability to return const references, you get the ability to have read only and mutable references to stuff within a struct co-exist.

For example, this won't compile:

    struct Something { z: usize }
    struct Foo<'a> { x: usize, y: &'a Something }
    impl<'a> Foo<'a> {
        fn bar(&mut self) -> &Something
        { let something = self.bar(); self.x += something.z; something }
    }
But if you could tell the borrow checker the mutable borrow of self can never modify z, then it would be safe. This would achieve that:

    struct Something { z: usize }
    struct Foo<'a> { x: usize, y: &'a const Something }
    impl<'a> Foo<'a> {
        fn bar(&mut self) -> &const Something
        { let something = self.bar(); self.x += something.z; something }
    }
I've now had several instances where they would have let me win a battle with the borrow checker succinctly rather than the long work around I was forced to adopt. Const struct members allow you implement read only fields with having to hide them, and provide getters is icing on the cake.