The bytes and strings packages have a number of useful helpers to work with and convert the data from string to byte types, and vice versa. They allow the creation of buffers that work with a number of common I/O interfaces.
How to do it...
The following steps cover how to write and run your application:
- From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter1/bytestrings.
- Navigate to this directory.
- Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter1/bytestrings
You should see a file called go.mod that contains the following content:
module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter1/bytestrings
- Copy the tests from~/projects/go-programming-cookbook-original/chapter1/bytestrings or use this as an exercise to write some of your own code!
- Create a file calledbuffer.gowith the following contents:
package bytestrings
import (
"bytes"
"io"
"io/ioutil"
)
// Buffer demonstrates some tricks for initializing bytes
//Buffers
// These buffers implement an io.Reader interface
func Buffer(rawString string) *bytes.Buffer {
// we'll start with a string encoded into raw bytes
rawBytes := []byte(rawString)
// there are a number of ways to create a buffer from
// the raw bytes or from the original string
var b = new(bytes.Buffer)
b.Write(rawBytes)
// alternatively
b = bytes.NewBuffer(rawBytes)
// and avoiding the initial byte array altogether
b = bytes.NewBufferString(rawString)
return b
}
// ToString is an example of taking an io.Reader and consuming
// it all, then returning a string
func toString(r io.Reader) (string, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return "", err
}
return string(b), nil
}
- Create a file calledbytes.gowith the following contents:
package bytestrings
import (
"bufio"
"bytes"
"fmt"
)
// WorkWithBuffer will make use of the buffer created by the
// Buffer function
func WorkWithBuffer() error {
rawString := "it's easy to encode unicode into a byte
array"
b := Buffer(rawString)
// we can quickly convert a buffer back into byes with
// b.Bytes() or a string with b.String()
fmt.Println(b.String())
// because this is an io Reader we can make use of
// generic io reader functions such as
s, err := toString(b)
if err != nil {
return err
}
fmt.Println(s)
// we can also take our bytes and create a bytes reader
// these readers implement io.Reader, io.ReaderAt,
// io.WriterTo, io.Seeker, io.ByteScanner, and
// io.RuneScanner interfaces
reader := bytes.NewReader([]byte(rawString))
// we can also plug it into a scanner that allows
// buffered reading and tokenization
scanner := bufio.NewScanner(reader)
scanner.Split(bufio.ScanWords)
// iterate over all of the scan events
for scanner.Scan() {
fmt.Print(scanner.Text())
}
return nil
}
- Create a file called string.go with the following contents:
package bytestrings
import (
"fmt"
"io"
"os"
"strings"
)
// SearchString shows a number of methods
// for searching a string
func SearchString() {
s := "this is a test"
// returns true because s contains
// the word this
fmt.Println(strings.Contains(s, "this"))
// returns true because s contains the letter a
// would also match if it contained b or c
fmt.Println(strings.ContainsAny(s, "abc"))
// returns true because s starts with this
fmt.Println(strings.HasPrefix(s, "this"))
// returns true because s ends with this
fmt.Println(strings.HasSuffix(s, "test"))
}
// ModifyString modifies a string in a number of ways
func ModifyString() {
s := "simple string"
// prints [simple string]
fmt.Println(strings.Split(s, " "))
// prints "Simple String"
fmt.Println(strings.Title(s))
// prints "simple string"; all trailing and
// leading white space is removed
s = " simple string "
fmt.Println(strings.TrimSpace(s))
}
// StringReader demonstrates how to create
// an io.Reader interface quickly with a string
func StringReader() {
s := "simple string\n"
r := strings.NewReader(s)
// prints s on Stdout
io.Copy(os.Stdout, r)
}
- Create a new directory named example and navigate to it.
- Create a main.go file with the following contents:
package main
import "github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter1/bytestrings"
func main() {
err := bytestrings.WorkWithBuffer()
if err != nil {
panic(err)
}
// each of these print to stdout
bytestrings.SearchString()
bytestrings.ModifyString()
bytestrings.StringReader()
}
- Run go run ..
- You may also run the following:
$ go build
$ ./example
You should see the following output:
$ go run .
it's easy to encode unicode into a byte array ??
it's easy to encode unicode into a byte array ??
it'seasytoencodeunicodeintoabytearray??true
true
true
true
[simple string]
Simple String
simple string
simple string
- If you copied or wrote your own tests, go up one directory and run go test, and ensure that all tests pass.
How it works...
The bytes library provides a number of convenience functions when working with data. A buffer, for example, is far more flexible than an array of bytes when working with stream-processing libraries or methods. Once you've created a buffer, it can be used to satisfy an io.Reader interface so that you can take advantage of ioutil functions to manipulate the data. For streaming applications, you'd probably want to use a buffer and a scanner. The bufio package comes in handy for these cases. Sometimes, using an array or slice is more appropriate for smaller datasets or when you have a lot of memory on your machine.
Go provides a lot of flexibility in converting data between interfaces when using these basic types—it's relatively simple to convert between strings and bytes. When working with strings, thestringspackage provides a number of convenience functions to work with, search, and manipulate strings. In some cases, a good regular expression may be appropriate, but most of the time, thestringsandstrconvpackages are sufficient. Thestringspackage allows you to make a string look like a title, split it into an array, or trim whitespace. It also provides aReaderinterface of its own that can be used instead of thebytespackage reader type.