Slide 19 of 74

The characters of a Str

proc main(): void {
	s := "café au lait"

	echo len(s)                  // 12 characters
	echo bytes(s)                // 13 bytes — é takes two

	if s bounds 3 {
		echo s[3]                // é, the fourth character
		echo s[0:3]              // café — both bounds inclusive
	}

	// A position from indexOf is one the string really has, so the
	// slice taken at it needs no guard of its own.
	if indexOf(s, "au") is Result.Ok(at) {
		echo s[at:]              // au lait
	}

	for each c in split("bee", "") {
		echo c
	}
}

A Str is a sequence of characters, and everything addresses it as one. len counts characters where bytes counts the UTF-8 they take, so for "café" they are 4 and 5. s[0] is the first character, as a one-character Str, and s[1:3] is characters one to three, both bounds inclusive.

Those are proved in range exactly as a vector's are, with one difference: a string never has a length the compiler knows, because there is no Str[3] for text. So even s[1] on a literal sitting right there needs a guard, or a position indexOf answered with.

Nothing writes into a Str: s[0] = "x" is a compile error, because characters are not all the same width and writing one would move every character after it. Build the new string instead. for each does not walk a Str either — split(s, "") is its characters, as a vector.