🐹 Go - Strings
Go has good native libraries for working with strings.
String is a slice of bytes []byte
. String itself does not care anything about encodings, they are just bytes and a byte is alias for uint8
. Output depends how your read them, but you can check if a string is UTF-8 with ValidString()
in unicode/utf8
. Go source code is always UTF-8.
package main
import "fmt"
func main() {
const text = "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98"
fmt.Println(text)
for i := 0; i < len(text); i++ {
// Print in hexadecimal format.
fmt.Printf("%x ", text[i])
}
fmt.Printf("\n\n")
// Note that some characters are more than one byte.
const placeOfInterest = `⌘`
fmt.Printf("%s", placeOfInterest)
fmt.Printf("\n")
for i := 0; i < len(placeOfInterest); i++ {
fmt.Printf("%x ", placeOfInterest[i])
}
fmt.Printf("\n\n")
// To interate over characters, use range.
const nihongo = "日本語"
for index, runeValue := range nihongo {
fmt.Printf("%#U starts at byte position %d\n", runeValue, index)
}
}
len
on strings tells the number of bytes, not characters. RuneCountInString()
in unicode/utf8
tells the number of runes, not characters.
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
text := "♥"
fmt.Println(len(text)) // => 3
fmt.Println(utf8.RuneCountInString(text)) // => 1
text2 := "é"
fmt.Println(len(text2)) // => 3
fmt.Println(utf8.RuneCountInString(text2)) // => 2
}
__Use conversions to do precise operations on strings. Converting between string
and []byte
is very efficient.
package main
import "fmt"
func main() {
x := "text"
xbytes := []byte(x)
xbytes[0] = 'T'
fmt.Println(string(xbytes)) // Text
}
Strings can be raw literals or interpreted literals. Raw literals use backticks ``, and may contain newlines and backslashes. Interpreted literals use double quotes "", where all special characters must be escaped.
package main
import "fmt"
func main() {
// These are equal.
fmt.Println(`abc`)
fmt.Println("abc")
// These are equal.
fmt.Println(`日本語`)
fmt.Println("日本語")
// These are equal.
fmt.Println(`\n
\n`)
fmt.Println("\\n\n\\n")
// These are equal.
fmt.Println(`Hello, world!
`)
fmt.Println("Hello, world!\n")
}
String formatting using fmt
.
package main
import (
"fmt"
"os"
)
type point struct {
x, y int
}
func main() {
// fmt.Printf sends formatted string to os.Stdout.
fmt.Printf("%t\n", true) // %t, print boolean.
fmt.Printf("%b\n", 123) // %b, print binary, base 2.
fmt.Printf("%d\n", 123) // %d, print number, base 10.
fmt.Printf("%c\n", 123) // %c, print Unicode character
fmt.Printf("%x\n", 123) // %x, print hex, base 16, lowercase.
fmt.Printf("%X\n", 123) // %x, print hex, base 16, uppercase.
fmt.Printf("%f\n", 78.9) // %f, print float, no exponents.
fmt.Printf("%e\n", 78.9) // %e, print float using exponents, lowercase e.
fmt.Printf("%E\n", 78.9) // %E, print float using exponents, uppercase e.
fmt.Printf("%.2f %.2f\n", 1.2, 3.456) // %.2f, print with 2 decimals.
fmt.Printf("%s\n", "Hello!") // %s, print string.
fmt.Printf("%q\n", "Hello!") // %q, print quoted string with escapes.
fmt.Printf("%x\n", "Hello!") // %x, print hex.
fmt.Printf("|%6d|%6d|\n", 12, 345) // %6d, print with space padding to 6.
fmt.Printf("|%6s|%6s|\n", "foo", "b") // %6s, print with space padding to 6.
fmt.Printf("|%-6d|%-6d|\n", 12, 345) // %-6d, print aligned left.
fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // %-6s, print aligned left.
p := point{1, 2}
fmt.Printf("%v\n", p) // %v, print value.
fmt.Printf("%+v\n", p) // %+v, print value with field names.
fmt.Printf("%#v\n", p) // %#v, print code that produces the value.
fmt.Printf("%T\n", p) // %T, print type of a value.
fmt.Printf("%p\n", &p) // %p, print pointer.
// fmt.Sprintf returns the formatted string.
s := fmt.Sprintf("a %s", "string")
fmt.Println(s)
// fmt.Fprintf forwards the formatted string to the given io.Writer.
fmt.Fprintf(os.Stderr, "an %s\n", "error")
// fmt.Errorf returns an error with the formatted string.
err := fmt.Errorf("user with id %d not found.", 101)
fmt.Println(err)
}
String related functions are mostly in strings
.
package main
import (
"fmt"
"strings"
)
var p = fmt.Println
func main() {
p("Contains: ", strings.Contains("test", "es")) // => true
p("Count: ", strings.Count("test", "t") // => 2
p("HasPrefix: ", strings.HasPrefix("test", "te")) // => true
p("HasSuffix: ", strings.HasSuffix("test", "st")) // => true
p("Index: ", strings.Index("test", "e")) // => 1
p("Join: ", strings.Join([]string{"a", "b"}, "-")) // => a-b
p("Repeat: ", strings.Repeat("a", 5)) // => aaaaa
p("Replace: ", strings.Replace("foo", "o", "0", -1)) // => f00
p("Replace: ", strings.Replace("foo", "o", "0", 1)) // => f0o
p("Split: ", strings.Split("a-b-c-d-e", "-")) // => [a b c d e]
p("ToLower: ", strings.ToLower("TEST")) // => test
p("ToUpper: ", strings.ToUpper("test"))// => TEST
p()
p("Len: ", len("hello")) // => 5
p("Char:", "hello"[1]) // => 101
}