The Foundation of Go s

let's go

Basic do not want to write, too many duplicates too high, continue to learn go to today, it should be summarized,


development tool

GoLand 30-day free trial

LiteIDE Open Source, Cross-Platform Lightweight

Be careful

The same code block may not reinitialize a variable with the same name: =

Cannot use variables before they are defined, declaring that local variables are not used will compile errors

Omit var to use':='and':=' left test to declare a new variable!Appears in the body of a function

Are var vname1, vname2, vname3 = v1, v2, v3 and python alike, infer types automatically, assign values in parallel
val,err = Func1(var1)

Global variable declaration:
var (
    a int
    b bool


Value type

The basic data types of int, float, bool, string are of value type (please Baidu specifically), and use this type of variable to point directly to the value that exists in memory

When using = to assign the value of a variable to another variable, j=i, the in-memory I value is copied

Get the variable I memory address through &i, the value of the variable exists in the stack

reference type

Variable r1

Stores the memory address (pointer) where the r1 value is located, or the location of the first word in the memory address

r2=r1 Reference address skin, R1 value changed, all references to the value will point to the modified content

Type Conversion


var sum int = 17
var count int = 5
var mean float32
mean = float32(sum)/float32(count)


Can be used as an enumeration:

const (
    Unknown = 0
    Female = 1
    Male = 2

Functions in constant expressions must be built-in, otherwise they will compile

const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(a)


Variable constant, resets the first line to zero after the const keyword appears, and counts iota once + 1 for each new line constant declaration

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //Independent value, iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7, Recovery Count
            i          //8
    fmt.Println(a,b,c,d,e,f,g,h,i)//0 1 2 ha ha 100 100 7 8

const (
    i=1<<iota //1,<< means left shift 0 bits unchanged
    j=3<<iota //6, << 1 bit left, binary 110, 6
    k         //12 << 2 bits left to binary 1100,12
    l         //24 << Move 3 bits left to binary 11000,24
//Did you find the password?< n==* (2^n)


package main

import "fmt"

/** Functions declare global variables out of the box and can be used in entire and external packages.
** Global and local variables can have duplicate names, preferring local variables 
var a int = 20;

func main() {
   /* main Functions declare local variables, which is different from java*/
   var a int = 10
   var b int = 20
   var c int = 0

   fmt.Printf("main()In function a = %d\n",  a);
   c = sum( a, b);
   fmt.Printf("main()In function c = %d\n",  c);

/* Function Definition-Formal Parameters Used as Function Local Variables */
func sum(a, b int) int {
   return a + b;


var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
package main

import "fmt"

func main() {
   var n [10]int /* Array length is not variable; 10 arrays, index from 0 */
   var i,j int
   for i = 0; i < 10; i++ {
      n[i] = i + 100 /* Set element to i + 100 */

   for j = 0; j < 10; j++ {
      fmt.Printf("Element[%d] = %d\n", j, n[j] )

//Multidimensional array, var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
a = [3][4]int{  
 {0, 1, 2, 3} ,   /*  First row index is 0 */
 {4, 5, 6, 7} ,   /*  Second row index is 1 */
 {8, 9, 10, 11},   /* The third row index is 2 */
}//You can also combine the last line and the second to last line into {8, 9, 10, 11} 


Is it a new concept?There's always a shadow you're familiar with

First mention: make initializes and returns reference T, new initializes a pointer to a type*T

Slices are abstract, dynamic arrays of arrays, so I understand why I wrote them here. I'm very careful to copy, click, and write.

var identifier [] type//Unfixed length, appendable elements
var slice1 []type = make([]type, len)//make() function to create slices
package main

import "fmt"

func main() {
   numbers := []int{0,1,2,3,4,5,6,7,8}  //Create Slices

   fmt.Println("numbers ==", numbers)//Print the original slice

   fmt.Println("numbers[1:4] ==", numbers[1:4])//Print subslices from index 1 (inclusive) to index 4 (excluded)

   fmt.Println("numbers[:3] ==", numbers[:3])//Default lower limit is 0

   fmt.Println("numbers[4:] ==", numbers[4:])//The default upper limit is len(s)

   numbers1 := make([]int,0,5)//S: =make ([]int, len, cap), len array length is also the initial length of the slice, cap capacity is not equal to length, optional parameter 

   number2 := numbers[:2]//number2 is based on the underlying array of numbers, so we can get more elements from origin slice, unsafe

   var number3 = numbers[1:4:4]//[] Third value 4 restricts access to the underlying array of the original slice


func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)//%v Slices here
//Like what, list
func printSliceNew(){
   var numbers []int
   numbers = append(numbers, 2,3,4)//Add multiple elements at once
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)
   copy(numbers1,numbers)//Copy the contents of numbers to numbers1


Memory address of pointer variable to value: var var_name *var-type

var ip *int        /* Point to Integer*/

*ip gets what the pointer is pointing to; when we first learned c++, this address somehow surrounded the baby, haha~sweat

Null pointer: An unassigned pointer with a value of nil indicating 0 or null

package main

import "fmt"

const MAX int = 3

func main() {
   a := []int{10,100,200}
   var i int
   var ptr [MAX]*int;

   for  i = 0; i < MAX; i++ {
      ptr[i] = &a[i] /* Integer address assignment to pointer array */

   for  i = 0; i < MAX; i++ {
      fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
   /* Define local variables */
   var a int = 100
   var b int= 200

   fmt.Printf("Before swap a Value of : %d\n", a )
   fmt.Printf("Before swap b Value of : %d\n", b )

   /* Call function to exchange values
   * &a The address to the a variable, notice here
   * &b The address to the b variable, notice here
   swap(&a, &b);

   fmt.Printf("After exchange a Value of : %d\n", a )
   fmt.Printf("After exchange b Value of : %d\n", b )

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* Save the value of the x address */
   *x = *y      /* Assign y to x */
   *y = temp    /* Assign temp to y */

structural morphology

Isn't it unfamiliar, does the entity know?Are you happy to be here, wow~Go

type struct_variable_type struct {
   member definition
   member definition
variable_name := structure_variable_type {value1, value2...valuen}
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen
//Or is it abstract???
package main

import "fmt"

type Books struct {
   title string
   author string//Property capitalization can be accessed by other packages or not by this package only
   subject string
   book_id int

func main() {

    // Create a new structure
    fmt.Println(Books{"Go language", "", "Go Language Tutorial", 6495407})

    // You can also use the key => value format
    fmt.Println(Books{title: "Go language", author: "", subject: "Go Language Tutorial", book_id: 6495407})

    // Ignored field is 0 or empty
   fmt.Println(Books{title: "Go language", author: ""})

   var Book1 Books        /* Declare Book1 as a Books type */
    /* book 1 describe */
   Book1.title = "Go language" = ""
   Book1.subject = "Go Language Tutorial"
   Book1.book_id = 6495407

   fmt.Printf( "Book 1 title : %s\n", Book1.title)//%d is a number

   struct_pointer = &Book1//Address to store structure variables
func printBook( book *Books ) {
   fmt.Printf( "Book title : %s\n", book.title)
   fmt.Printf( "Book book_id : %d\n", book.book_id)


map is fine, it's not too bad. Of course, I'm kidding, there's no standard for perfection

Definition is about the same as before

/* Declare variable, default map is nil */
var map_variable map[key_data_type]value_data_type
/* Use make function */
map_variable := make(map[key_data_type]value_data_type)
package main

import "fmt"

func main() {
    var countryCapitalMap map[string]string /*Create a collection */
    countryCapitalMap = make(map[string]string)

    /* map Insert a key - value pair for each country's capital */
    countryCapitalMap [ "France" ] = "Paris"
    countryCapitalMap [ "Italy" ] = "Rome"

    delete(countryCapitalMap, "France")

    /*Use keys to output map values */
    for country := range countryCapitalMap {
        fmt.Println(country, "The capital is", countryCapitalMap [country])

    /*See if an element exists in the collection */
    capital, ok := countryCapitalMap [ "American" ] /*If true, exists, otherwise does not exist */
    /*fmt.Println(capital) */
    /*fmt.Println(ok) */
    if (ok) {
        fmt.Println("American First of all", capital)
    } else {
        fmt.Println("American No head exists")
func test(){
   countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome", "Japan": "Tokyo", "India": "New delhi"}


Bitwise Operators

Other operators are simpler, and of course this one is simpler, but they are less commonly used and require thinking.

Before you say this, do 1 and 0 have any special meaning? If you know, you will understand better. ~Simple Baidu


Bitwise And, simply speaking, the binary bits involved in the operation are all 1 to get 1, the others are 0

I Bitwise Or, Binary Bit with 1 is 1

^Bitwise XOR, Binary Bit Same 0 Different 1

<< Move left, mentioned more or less above, move left n bits = n times 2, binary bits all move left n bits, high bits discard, position complement 0

>Move right, divided by the n-th power of 2

Other Operators

The first one is somewhat confusing, &as mentioned above, returns the address where the variable is stored, &a; returns the actual address of the variable a

*Pointer variable, who reminds me of c++?,*a; pointer variable

Operator Priority

From High to Low * /%< >> &^ + - | ^ ==! = < <= > > >== & & || cue parentheses here


Conditional statement

Commonly used if else, switch not to mention, note: there is no trinomial operator oh!

The select statement resembles a switch and randomly executes a runnable case, knowing that there is a case if none will be blocked


func function_name( [parameter list] ) [return_types] {
   //Function Body
package main

import "fmt"

func swap(x, y string) (string, string) {
   return y, x

func main() {
   a, b := swap("Google", "Runoob")
   fmt.Println(a, b)


Get the capacity of array, slice, channel type


Access restrictions were mentioned when slicing above, and append can break through them by expanding the slice and returning new slice values

Once the expansion operation exceeds the capacity of the slice value being operated on, the underlying array of slices is replaced and the copy function is called


copy(var1,var2) The second element is copied to the first parameter: Minimum copy principle, number of elements copied = length of the shorter one



When it comes to recursion, play with yourself. Simple for loops can also be powerful, so remember to set the exit criteria. Dead loops aren't a good thing

package main

import "fmt"

func fibonacci(n int) int {
  if n < 2 {
   return n
  return fibonacci(n-2) + fibonacci(n-1)

func main() {
    var i int
    for i = 0; i < 10; i++ {
       fmt.Printf("%d\t", fibonacci(i))

Range range

The elements of the iteration array, slice, channel, set map in the for loop;

Arrays and slices return element indexes and their values, collections return key/value pairs

package main
import "fmt"
func main() {
    //This is how we use range to find the sum of a slice.Using arrays is similar to this
    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    fmt.Println("sum:", sum)//sum:9
    //Using range on an array passes in two variables, index and value.For the example above, we don't need to use the ordinal of this element, so we omitted it with the blank character''.Sometimes we really need to know its index.
    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)//index:1
    //range can also be used on map key-value pairs.
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)//a -> apple b -> banana
    //range can also be used to enumerate Unicode strings.The first parameter is the index of the character, and the second is the character itself (the value of Unicode).
    for i, c := range "go" {
        fmt.Println(i, c)//0 103 1 111



Does the skeleton of a project come out, influenced by java? This interface can not be accepted more or less, just use more

package main

import (
//phone interface
type Phone interface {
    call()//call method

type NokiaPhone struct {

func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")

type IPhone struct {

func (iPhone IPhone) call() {
    fmt.Println("I am iPhone, I can call you!")

func main() {
    var phone Phone//Defines a variable that should have phone type

    phone = new(NokiaPhone)//Assignment to NokiaPhone the call of NokiaPhone

    phone = new(IPhone)//Assignment to IPhone for IPhone


Combination: Pseudo Integration

func (e *Poem) ShowTitle() {
type Poem struct {
    Title  string
    Author string
    intro  string

type ProsePoem struct {
    Poem//Combining Poem methods and properties
    Author string
prosePoem := &ProsePoem{
        Poem: Poem{
            Title:  "Jack",
            Author: "slow",
            intro:  "simple",
        Author: "test",
//There are conflicts of attributes, mainly on the periphery: I did not understand,_
//Accessing Author, which defaults to ProsePoem, requires accessing ProsePoem.Poem.Author in Poem 
prosePoem.Poem.Author = "Heine"

Concurrency, protocol

M: Kernel Threads

G:go routine concurrent minimum logic unit

P: Processor, execution G context, each P maintains a local go routine queue and a global go routine queue

The number of P is determined by gomaxprocs at initialization

The number of G s exceeds the processing power of M and there is still free P, runtime automatically creates a new M

M gets P to work, order of G: local queue > global queue > other P queues, all queue has no available G, M returns P and hibernates

go f(x,y,z) opens a new go routine runtime thread and the same address space is shared by the go routine of all of the same program

package main

import (

func say(s string) {
        for i := 0; i < 2; i++ {
                time.Sleep(10 * time.Millisecond)
                //runtime.Gosched() voluntarily gives up and throws G into the global queue

func main() {
        go say("world")
        say("hello")//Finish executing main thread, go* has no chance
runtime.GOMAXPROCS(n)//Specify multi-core, goroutine is in one thread, running in turn by not stopping giving up time slices

Channel channel

The defau lt is synchronous, <-Specifies the direction of the channel, does not specify a two-way channel

Default no buffer, sender send must have receiver receive, otherwise block

A data structure for transferring data that can be used to synchronize and communicate between goroutine s by transferring a specified type of value

package main

import (

func fibonacci(n int, c chan int) {
        x, y := 0, 1
        for i := 0; i < n; i++ {
                c <- x//Send x to channel ch; value, ok:= <-ch1 OK table channel state, true valid false, guess
                x, y = y, x+y
        close(c)//Duplicate shutdown causes a run exception

func main() {
        c := make(chan int, 10)//Create a channel with a buffer size of 10
        go fibonacci(cap(c), c)
        // range traverses each data received from the channel because c is sending 10
        // The channel is closed after the data, so here our range function receives 10 data
        // Then it's over.If the c channel above is not closed, then the range function will not
        // It ends, blocking when the eleventh data is received.
        for i := range c {


No exception mechanism, using panic/recover y mode to handle

panic generally causes the program to hang, printing the call stack: panic takes the function to defer and passes it up, whether defer is like final.

package main//

import (

func main() {

//GoLanguage pursues simplicity and elegance, so GoLanguage does not support traditional try...catch...finally, designers believe that mixing exceptions with control structures can easily confuse code.Do not replace errors with exceptions, let alone control processes.Use Exception handling introduced in Go only when you encounter a real exception (such as dividing by zero): defer, panic, recover
//Panic can be raised anywhere, but recover y is only valid in functions called by defer
func GO() {
	fmt.Println("I am GO,There are no exceptions. I'm doing it normally.")

func PHP() {
	// You must declare defer first, otherwise you cannot catch a panic exception, that is, you must register the function before you can call it
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("Finally captured panic Exceptions generated:", err) // Here err is actually what panic is passing in
			fmt.Println("I am defer Anonymous function in, I caught panic Exception, I want to recover,Come back.")
	}() //Note that this () calls the anonymous function and does not report expression in defer must be function call

	panic("I am PHP,I'm going to throw an exception. Wait defer Will pass recover Catch this exception, when I catch it, in PHP There will be no output in the defer The output is captured and processed to make the subsequent programs run properly.Notice, however, that PHP In a function, line up panic Later code will not execute.")
	fmt.Println("I am PHP in panic What to print later.But I can never print it out.Because logic does not revert to panic At that point, the function will still be defer Then return, that is, execute to defer After that, the program returns directly to the main()Next, start execution PYTHON()")

func PYTHON() {
	fmt.Println("I am PYTHON,No, defer come recover capture panic Exception, I will not be executed normally.")


It also uses defer code blocks to add a function call after the function returns normally, that is, after returning, and FIFO

When the package defer function returns, at the end of execution, and when the panic occurs in the goroutine where it is located: the time for defer execution is up, bah~~

func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
    defer src.Close()//Turn off variables used in cleanup src

    dst, err := os.Create(dstName)
    if err != nil {
    defer dst.Close()

    return io.Copy(dst, src)

Anonymous return value, named return value

**defer Execution process: create retValue and intValue=result, whether there is defer, execute, return the return value just created retvalue
** defer The modification in is performed on the result, not the retValue return but the retValue
func returnValues() int {
    var result int
    defer func() {
    return result
**Return values are defined when the method is defined, and no retValue procedure is created. Result is retValue, and defer's modifications to the result are also directly returned.
func namedReturnValues() (result int) {
    defer func() {
    return result
//Getting resources may return err parameters, optionally ignoring the returned err parameters but using defer delay release requires determining whether err exists
resp, err := http.Get(url)
// Determine if the operation was successful first
if err != nil {
    return err
defer resp.Body.Close()// If the operation succeeds, perform the Close operation again

defer will not be executed when os.Exit is called

Package Import

    . "fmt" //The package name of the prefix can be omitted, and fmt.Println ("hello go") is written as Println ("hello go")
    f "fmt"//Alias, f.Println ("hello go")
    _ "" //Instead of referencing the methods in the package, the Init() function is automatically executed when the package is imported to do the initialization required


Write these, see more and more information, want to say: nothing, fur does not count

Fate~Although you're not a woodchuck, it doesn't affect others to think of you as a woodchuck

Tags: Go PHP Python less

Posted on Mon, 04 May 2020 15:48:12 -0400 by johnnyboy16