Package references and package specifications
A code package can consist of several Go source files. The source files of a code package must all be in the same directory. All source files in a directory (excluding subdirectories) must be in the same code package, that is, the package PKgname statement at the beginning of these source files must be consistent. So, a code package corresponds to a directory (no subdirectories) and vice versa. The directory that corresponds to a code package is called the directory of the code package, but specifies that for the Go official toolchain, a code package with an internal directory name is considered a special code package that can only be imported from the immediate parent (and subdirectories of that parent) of the internal directory. For example, code packages… / / internal a/b/c/d/e/f and… /a/b/c/internal can only be imported to paths containing… / A /b/c prefix code package introduced.
init
function
Within a code package, or even a source file, you can declare several functions called init. These init functions must take no input arguments and return no results.
Note: We cannot declare package-level variables, constants, or types called init.
At runtime, each init function is executed (serially) and only once when the package is loaded, before entering the main entry function
package main
import "fmt"
func init(a) {
fmt.Println("hi,", bob)
}
func main(a) {
fmt.Println("bye")}func init(a) {
fmt.Println("hello,", smith)
}
func titledName(who string) string {
return "Mr. " + who
}
var bob, smith = titledName("Bob"), titledName("Smith")
Copy the code
Init functions declared in the same source file will be called from top to bottom,
String in Go
The string type is an important type in Go. The internal structure of the string type is declared as follows:
type _string struct {
elements *byte // References the underlying byte
len int // Number of bytes in the string
}
Copy the code
Unlike other languages, string types are comparable and do not use functions. Values of the same string type can be called == and! = comparison operator to compare. And like integer/floating point numbers, values of the same string type can be compared using the >, <, >=, and <= comparison operators. When two string values are compared, their underlying bytes are compared one by one. If one string is a prefix of another string, and the other string is longer, the other string is the larger of the two.
Since Go has no classes, common string operations are placed in strings, and aString methods can be used for slicing and indexing,
Channels in Go
Go also supports several traditional data synchronization technologies, but only channels are first-class citizens. Channels are a type of Go, so we can use channels without importing any code packages. Several traditional data synchronization techniques are provided in the SYNC and SYNC/Atomic standard library packages. Channels can be considered the second major feature of Go after coroutines,
Like array, slice, and map types, each channel type has an element type. A channel can only pass values of its element type.
A channel can be bidirectional or unidirectional.
-
The literal form chan T represents a bidirectional type with element type T. The compiler allows receiving and sending data from and to values of this type.
-
The literal form chan< -t represents a one-way send channel type of element type T. The compiler does not allow data to be received from values of this type.
-
The literal form <-chan T represents a one-way receive channel type of element type T. The compiler does not allow sending data to a value of this type.
The values of two-way channel chan T can be implicitly converted to one-way channel types chan< -t and <-chan T, but not vice versa (even explicitly). The values of the types chan< -t and <-chan T cannot be converted to each other.
Each channel value has a capacity attribute. The meaning of this property is explained in the next section. A channel with a capacity of 0 is called an unbuffered channel, and a channel with a capacity of 0 is called a buffered channel.
The zero value of a channel type is also represented by pre-declared nil. A non-zero channel value must be created using the built-in make function. For example, make(chan int, 10) creates a channel value of type int. The second parameter specifies the capacity of the channel to be created. This second argument is optional, and its default value is 0
Channel operation
There are five channel-related operations in Go. Given a channel (value) of CH, the syntax or function calls for these five operations are listed below.
- Calling built-in functions
close
To close a channel:
close(ch)
The argument passed to the close call must be a channel value, and the channel value cannot be received one-way.
- Use the following syntax to channel
ch
Send a valuev
:
ch <- v
V must be able to assign to the element type of channel CH. Ch cannot be a one-way receiving channel. <- is called the data send operator.
- Use the following syntax from the channel
ch
Receive a value:
<-ch
If a channel operation is not permanently blocked, it always returns at least one value of type the element type of channel CH. Ch cannot be a one-way transmission channel. <- is called the data receive operator, and yes it has the same representation as the data send operator.
In most cases, a data receive operation can be thought of as a single-valued expression. However, when a data receive operation is used as a unique source value in an assignment statement, it can return an optional second Boolean value of indeterminate type, thus becoming a multi-valued expression. An indeterminate Boolean value of this type indicates whether the first received value was sent before the channel was closed. (From a later section, we will learn that we can receive an infinite number of values from a closed channel.)
Example of a data receive operation being used as a source value in an assignment:
v = <-ch
v, sentBeforeClosed = <-ch
Copy the code
- Query the capacity of a channel:
cap(ch)
Cap is a built-in function that was covered in the container Types article. Cap returns a value of type int.
- Query the length of a channel:
len(ch)
Where Len is a built-in function that was covered in the container Types article. Len’s return value is also of type int. The length of a channel is the number of elements currently sent to the channel that have not yet been received.
Most of the basic operations in Go are unsynchronized. In other words, none of them are concurrency safe. These operations include assignment, parameter passing, and various container value operations. However, the five channel-related operations listed above are already synchronized, so they can run safely in a concurrent coroutine without other synchronization operations.
Note: Assignment of channels, like assignment of any other type of value, is unsynchronized. Similarly, assigning a value just received from one channel to another is unsynchronized
A simple example of a request/response implemented over a non-buffered channel:
package main
import (
"fmt"
"time"
)
func main(a) {
c := make(chan int) // a non-buffered channel
go func(ch chan<- int, x int) {
time.Sleep(time.Second)
// <-ch // This operation does not compile
ch <- x*x // blocks here until the sent value is received
}(c, 3)
done := make(chan struct{})
go func(ch <-chan int) {
n := <-ch // block here until a value is sent to c
fmt.Println(n) / / 9
Ch < -123 // This operation failed to compile
time.Sleep(time.Second)
done <- struct{}{}
}(c)
<-done // block here until a value is sent to done
fmt.Println("bye")}Copy the code
reference
More details can be viewed gfw.go101.org/article/101… Check your profile for more.