Skip to content

Latest commit

 

History

History
187 lines (156 loc) · 6.6 KB

2.07.md

File metadata and controls

187 lines (156 loc) · 6.6 KB

2.07 The fmt Package

Let's have a look at the fmt package, and how to read the Go standard library package documentation. We'll start with the fmt package, and look at format printing, and the different format printing verbs we can use.

package main

import (
	"fmt"
)

var a int
var b string = "James Bond"
var c bool
var d bool = true

func main() {
	e := 42
	f := "Shaken not stirred"
	g := `Miss Moneypenny says, "Helloooooo, James"`  // backticks allow us to use a string raw literal
	h := `Q says, 
	"I have some new toys for you, James."
	`
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
	fmt.Println(e)
	fmt.Println(b, "says, ", f)
	fmt.Println(g)
	fmt.Println(h)
}

returns:

0
James Bond
false
true
42
James Bond says,  Shaken not stirred
Miss Moneypenny says, "Helloooooo, James"
Q says, 
	"I have some new toys for you, James."
	

Program exited.

Let's take a look at using format printing for printing out the type. We can start by viewing the fmt documentation.

If we click index it gives us an index of what we can use the package for:

func Errorf(format string, a ...interface{}) error
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
func Scan(a ...interface{}) (n int, err error)
func Scanf(format string, a ...interface{}) (n int, err error)
func Scanln(a ...interface{}) (n int, err error)
func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string
func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
type Formatter
type GoStringer
type ScanState
type Scanner
type State
type Stringer

So far, we have been using fmt.Println(), there are also fmt.Printf() and fmt.Print(). fmt.Println() gives you a new line, fmt.Print() does not. fmt.Printf() does format printing. Printf formats according to a format specifier (or format verb) and writes to standard output. It returns the number of bytes written and any write error encountered.

func Printf(format string, a ...interface{}) (n int, err error)

fmt.Printf() takes a format of type string. In this case, format is just an identifier. It could have been called anything, but it needs to be of type string and ...interface{} (the variatic parameter ... and empty interface interface{}) shows it will take an unlimited number of values of any type.

So, what are the format printing verbs? "The format 'verbs' are derived from C's but are simpler."

%v is useful for showing us the value, whether it's an int, string, bool, etc.

package main

import (
	"fmt"
)

var a int
var b string = "James Bond"
//var c bool
//var d bool = true

func main() {
	//e := 42
	//f := "Shaken not stirred"
	//g := `Miss Moneypenny says, "Helloooooo, James"`  // backticks allow us to use a string raw literal
	//h := `Q says, 
	//"I have some new toys for you, James."
	//`
	fmt.Printf("%v\n", a)
	fmt.Printf("%v", b)
}

Unlike fmt.Println, fmt.Printf does not give us a new line. We can add \n for a new line. In the Go language spec documentation, under Rune Literals](https://golang.org/ref/spec#Rune_literals) there's documentation about the single-character escapes:

\a   U+0007 alert or bell
\b   U+0008 backspace
\f   U+000C form feed
\n   U+000A line feed or newline
\r   U+000D carriage return
\t   U+0009 horizontal tab
\v   U+000b vertical tab
\\   U+005c backslash
\'   U+0027 single quote  (valid escape only within rune literals)
\"   U+0022 double quote  (valid escape only within string literals)

\n and \t are two that probably get used the most.

Other than using %v, we can also use %#v (a Go-syntax representation of the value), %T to output the type of the value. Try playing with different escapes and verbs on the Go Playground

package main

import (
	"fmt"
)

var a int
var b string = "James Bond"

func main() {
	fmt.Printf("%v\n", a)
	fmt.Printf("%v\n", b)
	fmt.Printf("%#v\n", a)
	fmt.Printf("%#v\n", b)
	fmt.Printf("%T\n", a)
	fmt.Printf("%T\n", b)
	fmt.Printf("%T\t%T", a, b)
}

Let's take another look at the fmt index, particularly the fmt.Sprint() function. fmt.Sprint() is a string print. You can see it returns a string.

Sprint formats using the default formats for its operands and returns the resulting string.

func Sprintf(format string, a ...interface{}) string

So, let's try it out on the Go playground:

package main

import (
	"fmt"
)

var a int
var b string = "James Bond"

func main() {
	fmt.Printf("%v\n", a)
	fmt.Printf("%v\n", b)
	fmt.Printf("%#v\n", a)
	fmt.Printf("%#v\n", b)
	fmt.Printf("%T\n", a)
	fmt.Printf("%T\n", b)
	fmt.Printf("%T\t%T\n", a, b)
	
	s := fmt.Sprint(a, " something more ", b)
	fmt.Println(s)
	s2 := fmt.Sprintf("%v\t%T\t%T\n", "to pass in", a, b)
	fmt.Println(s2)
}

OK, so that's Print, Printf, Println, Sprint, Sprintf, Sprintln. We can see the pattern. There's also Fprint, or file print, where we can print to some sort of a writer. We'll learn about that later, where we could do something like Print, Printf, Println, but write about it to something like a response writer in a web app, like write about this in a response writer, and it will send that text as the server's response, because it's writing to a writer, or you could write it to a file. The IO writer is an interface which allows any value, which impliments that interface to be used there, so you could do it with an HTTP response writer or a file. This is polymorphism in action. But we'll get to that later. As well as scanning, which allows you to scan stuff.

That's some pretty interesting stuff from the fmt package.