Wouldn't any language with exceptions work here? You just define an indexing operator that throws an exception instead of crashing and handle that exception outside the unicode handling function.
The advantage of rusts error handling is that it is explicit. The compiler knows that a function might result in an error and forces the programmer to deal with it, or pass it along.
In an exception based language you might forget to deal with the error and have it crash "higher up" in the code.
I also suspect that there might be a performance benefit but I could be completely wrong about that
It's actually slower to not use exceptions and what you describe is not an advantage - exceptions also force you to deal with it or pass it along, if the exception is checked. Bounds check failures aren't of course because that would be incredibly inconvenient and unwieldy, and anyway, you'd just pass it all the way up the stack to some much higher level point which is the only place you can sanely do something (like not render the string at all).
> The advantage of rusts error handling is that it is explicit. The compiler knows that a function might result in an error and forces the programmer to deal with it, or pass it along.
Checked exceptions are explicit as well, though I'm not aware of a language that _only_ has checked exceptions.
> I also suspect that there might be a performance benefit but I could be completely wrong about that
Yes, this is a big advantage. Stack unwinding is very expensive.