Welcome To Golang By Example

Println vs Print vs Printf in Go (Golang)

Overview

Println, Print, and Printf are defined in the fmt package and are used to format a string and write to standard output

https://golang.org/pkg/fmt/

The basic difference between them is

Let’s see each of them in detail with examples

About Println function

Below is the function prototype of Println

func Println(a ...interface{}) (n int, err error)

Println takes a variable number of arguments where each argument is an empty interface. It returns the number of characters printed and any error if happens. Since the argument type is an empty interface we can pass any data type to it. We can pass a string, int, float, struct, or any other data type. Each of the arguments to the Println function is formatted according to the default format specifier of that argument type. For example, the struct will be formatted according to the below specifier

%v

This format specifier only prints the Value part in the struct. Let’s see an example

package main
import "fmt"
type employee struct {
    Name string
    Age  int
}
func main() {
    name := "John"
    age := 21
    fmt.Println("Name is: ", name)
    fmt.Println("Age is: ", age)
    e := employee{
        Name: name,
        Age:  age,
    }
    fmt.Println(e)
    fmt.Println("a", 12, "b", 12.0)

    
    bytesPrinted, err := fmt.Println("Name is: ", name)
    if err != nil {
	log.Fatalln("Error occured", err)
    }
    fmt.Println(bytesPrinted)
}

Output

Name is: John
Age is: 21
{John 21}
a 12 b 12
Name is: John
14

Some important points to note about the Println function

fmt.Println("Name is: ", name)

prints

Name is: John

Space is introduced automatically between the two arguments.

bytesPrinted, err := fmt.Println("Name is: ", name)
if err != nil {
    log.Fatalln("Error occured", err)
}
fmt.Println(bytesPrinted)

will output below

Name is: John
14

Number of bytesPrinted is 14 as 14 characters are outputted

About Print function

Function prototype of Print

func Print(a ...interface{}) (n int, err error)

The Print function is exactly the same as the Println function other than two differences

Let’s see an example for the same

package main

import "fmt"

type employee struct {
	Name string
	Age  int
}

func main() {
	name := "John"
	age := 21
	fmt.Print("Name is:", name, "\n")
	fmt.Print("Age is:", age, "\n")

	e := employee{
		Name: name,
		Age:  age,
	}

	fmt.Print(e, "\n")

	fmt.Print("a", 12, "b", 12.0, "\n")

	fmt.Print(12, 12.0, "\n")
        
        
        bytesPrinted, err := fmt.Print("Name is: ", name, "\n")
	if err != nil {
		log.Fatalln("Error occured", err)
	}
	fmt.Print(bytesPrinted)
}

Output

Name is:John
Age is:21
{John 21}
a12b12
12 12
Name is: John
14

Some important points to note about the Print function

fmt.Print(12, 12.0, "\n")

prints

12 12

while

fmt.Print("a", 12, "b", 12.0, "\n")

prints

a12b12

About Printf function

Function prototype of Printf

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

Printf is also a variadic function meaning that it can have multiple arguments. There are two important points about its argument list

The format or template string contains the actual string that needs to be formatted plus some formating verbs. These formating verbs tell how the trailing arguments will be formatted in the final string.  So basically the format string argument contains certain symbols which are replaced by trailing arguments.  

Eg

Printing a string variable

name := "John"
fmt.Printf("Name is: %s\n", name)

Printing an integer

age := 21
fmt.Printf("Age is: %d\n", age)

Printing a struct

For example, there are three format specifiers for printing a struct. 

That is why

fmt.Printf("Employee is %v\n", e)
fmt.Printf("Employee is %+v\n", e)
fmt.Printf("Employee is %#v\n", e)

prints below respectively

Employee is {John 21}
Employee is {Name:John Age:21}
Employee is main.employee{Name:"John", Age:21}

It is as per the explanation above.

Also, note that this function returns the number of characters printed and any error if happens. Unlike Println it does add a new line. You will have to add “\n” explicitly. 

Here is the working program for the same

package main

import (
	"fmt"
	"log"
)

type employee struct {
	Name string
	Age  int
}

func main() {
	name := "John"
	age := 21

	fmt.Printf("Name is: %s\n", name)
	fmt.Printf("Age is: %d\n", age)

	fmt.Printf("Name: %s Age: %d\n", name, age)

	e := employee{
		Name: name,
		Age:  age,
	}

	fmt.Printf("Employee is %v\n", e)
	fmt.Printf("Employee is %+v\n", e)
	fmt.Printf("Employee is %#v\n", e)

	bytesPrinted, err := fmt.Printf("Name is: %s\n", name)
	if err != nil {
		log.Fatalln("Error occured", err)
	}
	fmt.Println(bytesPrinted)
}

Output

Name is: John
Age is: 21
Name: John Age: 21
Employee is {John 21}
Employee is {Name:John Age:21}
Employee is main.employee{Name:"John", Age:21}
Name is: John
14

Notice that in below Printf

fmt.Printf("Name: %s Age: %d\n", name, age)

So basically the symbols or verbs in the format string argument are replaced by trailing arguments in orderIf the number of format specifiers in the format string does not match the number of next variable arguments then the format specifier will be printed as is. For example, in the below code, we have two format specifier

While the next variable number of arguments is only one. Hence when we print it then it will print the second format specifier as is with MISSING as warning

package main
import "fmt"
type employee struct {
    Name string
    Age  int
}
func main() {
    name := "John"
    fmt.Printf("Name is: %s %d\n", name)
}

Output

Name is: John %!d(MISSING)

Also, check out our Golang advance tutorial Series – Golang Advance Tutorial