Chapter 2. Go Language Essentials

In the previous chapter, we established the elemental characteristics that make Go a great language with which to create modern system programs. In this chapter, we dig deeper into the language's syntax to explore its components and features.

We will cover the following topics:

  • The Go source file
  • Identifiers
  • Variables
  • Constants
  • Operators

The Go source file

We have seen, in Chapter 1, A First Step in Go, some examples of Go programs. In this section, we will examine the Go source file. Let us consider the following source code file (which prints "Hello World" greetings in different languages):

The Go source file

golang.fyi/ch02/helloworld2.go

A typical Go source file, such as the one listed earlier, can be divided into three main sections, illustrated as follows:

  • The Package Clause:
          //1 Package Clause 
          package main 
    
  • The Import Declaration:
          //2 Import Declaration 
          import "fmt" 
          import "math/rand" 
          import "time" 
    
  • The Source Body:
          //3 Source Body 
          var greetings = [][]string{ 
            {"Hello, World!","English"}, 
            ... 
          } 
     
          func greeting() [] string { 
            ... 
          } 
     
          func main() { 
            ... 
          } 
    

The package clause indicates the name of the package this source file belongs to (see Chapter 6, Go Packages and Programs for a detailed discussion on package organization). The import declaration lists any external package that the source code wishes to use. The Go compiler strictly enforces package declaration usage. It is considered an error (compilation) to include an unused package in your source file. The last portion of the source is considered the body of your source file. It is where you declare variables, constants, types, and functions.

All Go source files must end with the .go suffix. In general, you can name a Go source file whatever you want. Unlike Java, for instance, there is no direct association between a Go file name and the types it declared in its content. It is, however, considered good practice to name your file something indicative of its content.

Before we explore Go's syntax in greater detail, it is important to understand some basic structural elements of the language. While some of these elements are syntactically bolted into the language, others are simple idioms and conventions that you should be aware of to make your introduction to Go simple and enjoyable.

Optional semicolon

You may have noticed that Go does not require a semicolon as a statement separator. This is a trait borrowed from other lighter and interpreted languages. The following two programs are functionally equivalent. The first program uses idiomatic Go and omits the semicolons:

Optional semicolon

The second version of the program, shown as follows, uses superfluous semicolons to explicitly terminate its statements. While the compiler may thank you for your help, this is not idiomatic in Go:

Optional semicolon

Although semicolons in Go are optional, Go's formal grammar still requires them as statement terminators. So, the Go compiler will insert semicolons at the end of source code lines that end with the following:

  • An identifier
  • A literal value for string, Boolean, numeric, or complex
  • A control flow directive such as break, continue, or return
  • A closing parenthesis or bracket such as ), }, or ]
  • The increment ++ or the decrement -- operator

Due to these rules, the compiler enforces strict syntactical forms that heavily influence source code style in Go. For instance, all code blocks must start with an open curly { brace on the same line as its preceding statement. Otherwise, the compiler may insert the semicolon in a location that breaks the code, as shown in the following if statement:

func main() { 
    if "a" == "a" 
    { 
      fmt.Println("Hello, World!") 
    } 
} 

Moving the curly brace to the next line causes the compiler to insert the semicolon prematurely, which will result in the following syntax error:

$> ... missing condition in if statement ... 

This is because the compiler inserted the semicolon after the if statement (if "a"=="a";), using the semicolon insertion rules discussed in this section. You can verify this by manually inserting a semicolon after the if condition statement; you will get the same error. This is an excellent place to transition into the next section, to discuss trailing commas in code blocks.

Multiple lines

Breaking up expressions into multiple lines must follow the semi-colon rules discussed in the previous section. Mainly, in a multi-line expression, each line must end with a token that prevents the premature insertion of a semi-colon, as illustrated in the following table. It should be noted that rows in the table with an invalid expression will not compile:

Expression

Valid

lonStr := "Hello World! " +
"How are you?"

Yes, the + operator prevents a premature semi-colon from being inserted.

lonStr := "Hello World! "
+ "How are you?"

No, a semi-colon will be inserted after the first line, semantically breaking the line.

fmt.Printf("[%s] %d %d %v",
str,
num1,
num2,
nameMap)

Yes, the comma properly breaks the expression.

fmt.Printf("[%s] %d %d %v",
str,
num1,
num2,
nameMap)

Yes, the compiler inserts a semi-colon only after the last line.

weekDays := []string{
"Mon", "Tue",
"Wed", "Thr",
"Fri"
}

No, the Fri line causes a premature semi-colon to be inserted.

weekDays2 := []string{
"Mon", "Tue",
"Wed", "Thr",
"Fri",
}

Yes, the Fri line contains a trailing comma, which causes compiler to insert a semi-colon at the next line.

weekDays1 := []string{"Mon", "Tue","Wed", "Thr","Fri"}

Yes, the semi-colon is inserted after the line with the closing bracket.

You may wonder why the Go compiler puts the onus on the developer to provide line-break hints to indicate the end of a statement. Surely, Go designers could have devised an elaborate algorithm to figure this out automatically. Yes, they could have. However, by keeping the syntax simple and predictable, the compiler is able to quickly parse and compile Go source code.

Note

The Go toolchain includes the gofmt tool, which can be used to consistently apply proper formatting rules to your source code. There is also the govet tool, which goes much further by analyzing your code for structural problems with code elements.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.71.21