[rust-dev] PSA: ~"string" is probably not what you want
pwalton at mozilla.com
Sun Apr 28 11:14:13 PDT 2013
On 4/28/13 10:57 AM, Lee Braiden wrote:
> Really? Strings can't just be compared with == ? To be honest, that
> alone is almost enough to put me off the language -- not only is it ugly
> and unwieldy, but it suggests a lot of limitations in the language's
> memory model / type system / operator overloading, which would also make
> my own code ugly and unwieldy.
> What's the problem with ==, or the difference with equiv(), exactly?
The problem is that `&str` and `~str` are not the same type. We could
change `Eq` so that it doesn't require the same type on the
left-hand-side and the right-hand-side, but that would complicate the
trait system quite a bit.
Currently, overloaded operators do not borrow. I guess we could change
overloaded operators (or maybe just `==` and `!=`?) to try to borrow the
left hand side and/or right hand side to make the types match. I think
this is *probably* OK. However, we need to be careful, because it's
exactly the kind of thing that could have unforeseen consequences.
"Strings should be comparable with `==` without allocating" is the kind
of thing that is "obviously true", but trying to do it without thinking
carefully about the ramifications of borrowing in overloaded operators
is problematic. We already have quite complex method lookup semantics
exactly to make things like this just work, and it has fallout when you
start having to get picky about how many dereferences you do.
To be honest, the tone of your message is a little frustrating, because
you jumped on one thing that's not ideal (that the different types
`~str` and `&str` cannot be compared with `==`), said something
inaccurate (that strings cannot be compared with `==`), and extrapolated
it to the idea that Rust's type system is "ugly and unwieldy". No, it's
just that we need to think carefully about how to handle this one case.
> there some way to make it just work, no matter what kind of strings
> you're comparing? Perhaps "foo" == (*x) would work, for example?
That doesn't work, because it makes the dynamically sized `str` a type,
which is incoherent. (It would lead to dynamically sized stack frames,
or structs or enums with infinite size, and so on.)
More information about the Rust-dev