Heh, I just remembered that Rust has like 6 or 7 ways to do strings too.
As for only needing them when you need them, how could it be otherwise? :-)
It's not the choice I would make, but my opinion doesn't really matter. Real world strings (UTF-8, WTF-8, UCS-16, arbitrary bytes) don't follow the rules 100% of the time, so you're always going to end up dealing with that complexity at runtime in one place or another. I think you might as well have one simple string type and accept that. This is what Go chose (not that I'm a regular Go user either).