golang 學習二:go程序編譯運行與變量


go 程序的編譯與運行

第一個go程序 'helloworld.go'

// 聲明包名,可以是任意名字,但只有main才可以編譯成二進制文件.exe
packge main

// 導入 fmt 標准包
import "fmt"

// 函數名 main 可以是任意的名字,但go文件的入口文件一般就定義為:main
func main() {
    fmt.Println("Hello world")  // 控制台打印: "Hello world"
}

編譯

# 編譯 helloworld.go 文件,生成 'helloworld.exe' 可執行的二進制文件
go build helloworld.go

編譯的詳細過程

# go 程序的詳細編譯過程,需要加一個 '-x' 參數
go build -x helloworld.go

G:\Golang\day01>go build -x helloworld.go
WORK=C:\Users\ADMINI~1\AppData\Local\Temp\go-build058986106
mkdir -p $WORK\b001\
cat >$WORK\b001\importcfg.link << 'EOF' # internal
packagefile command-line-arguments=C:\Users\Administrator\AppData\Local\go-build\b8\b82385b45455bcbdf17588943c44929778c0664c2bcdcce49612bd35efd7bd22-d
packagefile fmt=C:\Go\pkg\windows_amd64\fmt.a
packagefile runtime=C:\Go\pkg\windows_amd64\runtime.a
packagefile errors=C:\Go\pkg\windows_amd64\errors.a
packagefile internal/fmtsort=C:\Go\pkg\windows_amd64\internal\fmtsort.a
packagefile io=C:\Go\pkg\windows_amd64\io.a
packagefile math=C:\Go\pkg\windows_amd64\math.a
packagefile os=C:\Go\pkg\windows_amd64\os.a
packagefile reflect=C:\Go\pkg\windows_amd64\reflect.a
packagefile strconv=C:\Go\pkg\windows_amd64\strconv.a
packagefile sync=C:\Go\pkg\windows_amd64\sync.a
packagefile unicode/utf8=C:\Go\pkg\windows_amd64\unicode\utf8.a
packagefile internal/bytealg=C:\Go\pkg\windows_amd64\internal\bytealg.a
packagefile internal/cpu=C:\Go\pkg\windows_amd64\internal\cpu.a
packagefile runtime/internal/atomic=C:\Go\pkg\windows_amd64\runtime\internal\atomic.a
packagefile runtime/internal/math=C:\Go\pkg\windows_amd64\runtime\internal\math.a
packagefile runtime/internal/sys=C:\Go\pkg\windows_amd64\runtime\internal\sys.a
packagefile internal/reflectlite=C:\Go\pkg\windows_amd64\internal\reflectlite.a
packagefile sort=C:\Go\pkg\windows_amd64\sort.a
packagefile sync/atomic=C:\Go\pkg\windows_amd64\sync\atomic.a
packagefile math/bits=C:\Go\pkg\windows_amd64\math\bits.a
packagefile internal/oserror=C:\Go\pkg\windows_amd64\internal\oserror.a
packagefile internal/poll=C:\Go\pkg\windows_amd64\internal\poll.a
packagefile internal/syscall/execenv=C:\Go\pkg\windows_amd64\internal\syscall\execenv.a
packagefile internal/syscall/windows=C:\Go\pkg\windows_amd64\internal\syscall\windows.a
packagefile internal/testlog=C:\Go\pkg\windows_amd64\internal\testlog.a
packagefile syscall=C:\Go\pkg\windows_amd64\syscall.a
packagefile time=C:\Go\pkg\windows_amd64\time.a
packagefile unicode/utf16=C:\Go\pkg\windows_amd64\unicode\utf16.a
packagefile unicode=C:\Go\pkg\windows_amd64\unicode.a
packagefile internal/race=C:\Go\pkg\windows_amd64\internal\race.a
packagefile internal/syscall/windows/sysdll=C:\Go\pkg\windows_amd64\internal\syscall\windows\sysdll.a
packagefile internal/syscall/windows/registry=C:\Go\pkg\windows_amd64\internal\syscall\windows\registry.a
EOF
mkdir -p $WORK\b001\exe\
cd .
"C:\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build058986106\\b001\\exe\\a.out.exe" -importcfg "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build058986106\\b001\\importcfg.link" -buildmode=exe -buildid=Va9osQyTjZlRtuDFNn2t/jQDKertcdlkDzi7CCK_8/0q33Isr5dtp6VBFPeoXK/Va9osQyTjZlRtuDFNn2t -extld=gcc "C:\\Users\\Administrator\\AppData\\Local\\go-build\\b8\\b82385b45455bcbdf17588943c44929778c0664c2bcdcce49612bd35efd7bd22-d"
"C:\\Go\\pkg\\tool\\windows_amd64\\buildid.exe" -w "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build058986106\\b001\\exe\\a.out.exe" # internal
cp $WORK\b001\exe\a.out.exe helloworld.exe
rm -r $WORK\b001\

編譯后更改二進制的文件名

# 以上默認編譯出的exe文件為: helloworld.exe,若需要更改編譯后的二進制文件名字為: test.exe,則加一個 '-o' 參數 
go build -x -o test.exe helloworld.go

編譯過程中生成的臨時目錄

# go 程序在編譯時會生成一個臨時目錄,如果要看生成的臨時目錄,則需要加一個 '-work' 參數

go build -x -o test.exe -work helloworld.go

# WORK=C:\Users\ADMINI~1\AppData\Local\Temp\go-build037181318

G:\Golang\day01>go build -x -o test.exe -work helloworld.go
WORK=C:\Users\ADMINI~1\AppData\Local\Temp\go-build037181318
mkdir -p $WORK\b001\
cat >$WORK\b001\importcfg.link << 'EOF' # internal
packagefile command-line-arguments=C:\Users\Administrator\AppData\Local\go-build\b8\b82385b45455bcbdf17588943c44929778c0664c2bcdcce49612bd35efd7bd22-d
packagefile fmt=C:\Go\pkg\windows_amd64\fmt.a
packagefile runtime=C:\Go\pkg\windows_amd64\runtime.a
packagefile errors=C:\Go\pkg\windows_amd64\errors.a
packagefile internal/fmtsort=C:\Go\pkg\windows_amd64\internal\fmtsort.a
packagefile io=C:\Go\pkg\windows_amd64\io.a
packagefile math=C:\Go\pkg\windows_amd64\math.a
packagefile os=C:\Go\pkg\windows_amd64\os.a
packagefile reflect=C:\Go\pkg\windows_amd64\reflect.a
packagefile strconv=C:\Go\pkg\windows_amd64\strconv.a
packagefile sync=C:\Go\pkg\windows_amd64\sync.a
packagefile unicode/utf8=C:\Go\pkg\windows_amd64\unicode\utf8.a
packagefile internal/bytealg=C:\Go\pkg\windows_amd64\internal\bytealg.a
packagefile internal/cpu=C:\Go\pkg\windows_amd64\internal\cpu.a
packagefile runtime/internal/atomic=C:\Go\pkg\windows_amd64\runtime\internal\atomic.a
packagefile runtime/internal/math=C:\Go\pkg\windows_amd64\runtime\internal\math.a
packagefile runtime/internal/sys=C:\Go\pkg\windows_amd64\runtime\internal\sys.a
packagefile internal/reflectlite=C:\Go\pkg\windows_amd64\internal\reflectlite.a
packagefile sort=C:\Go\pkg\windows_amd64\sort.a
packagefile sync/atomic=C:\Go\pkg\windows_amd64\sync\atomic.a
packagefile math/bits=C:\Go\pkg\windows_amd64\math\bits.a
packagefile internal/oserror=C:\Go\pkg\windows_amd64\internal\oserror.a
packagefile internal/poll=C:\Go\pkg\windows_amd64\internal\poll.a
packagefile internal/syscall/execenv=C:\Go\pkg\windows_amd64\internal\syscall\execenv.a
packagefile internal/syscall/windows=C:\Go\pkg\windows_amd64\internal\syscall\windows.a
packagefile internal/testlog=C:\Go\pkg\windows_amd64\internal\testlog.a
packagefile syscall=C:\Go\pkg\windows_amd64\syscall.a
packagefile time=C:\Go\pkg\windows_amd64\time.a
packagefile unicode/utf16=C:\Go\pkg\windows_amd64\unicode\utf16.a
packagefile unicode=C:\Go\pkg\windows_amd64\unicode.a
packagefile internal/race=C:\Go\pkg\windows_amd64\internal\race.a
packagefile internal/syscall/windows/sysdll=C:\Go\pkg\windows_amd64\internal\syscall\windows\sysdll.a
packagefile internal/syscall/windows/registry=C:\Go\pkg\windows_amd64\internal\syscall\windows\registry.a
EOF
mkdir -p $WORK\b001\exe\
cd .
"C:\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build037181318\\b001\\exe\\a.out.exe" -importcfg "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build037181318\\b001\\importcfg.link" -buildmode=exe -buildid=Va9osQyTjZlRtuDFNn2t/jQDKertcdlkDzi7CCK_8/0q33Isr5dtp6VBFPeoXK/Va9osQyTjZlRtuDFNn2t -extld=gcc "C:\\Users\\Administrator\\AppData\\Local\\go-build\\b8\\b82385b45455bcbdf17588943c44929778c0664c2bcdcce49612bd35efd7bd22-d"
"C:\\Go\\pkg\\tool\\windows_amd64\\buildid.exe" -w "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build037181318\\b001\\exe\\a.out.exe" # internal
cp $WORK\b001\exe\a.out.exe test.exe

go run 直接編譯運行一體化

# 'go run' 可以直接先進行編譯后再運行

go run helloworld.go

G:\Golang\day01>go run helloworld.go
Hello world

# 加參數 '-x' 會打印出完整的過程(現編以后運行)
go run -x helloworld.go

# 加參數 '-n' 只會打印出編譯的過程,不會運行
go run -n helloworld.go

G:\Golang\day01>go run -n helloworld.go
mkdir -p $WORK\b001\
cat >$WORK\b001\importcfg.link << 'EOF' # internal
packagefile command-line-arguments=C:\Users\Administrator\AppData\Local\go-build\13\1393673cb1fc6a992fd0d9e1e30f237e0b61dfd69337713c72ba8ff94fef9496-d
packagefile fmt=C:\Go\pkg\windows_amd64\fmt.a
packagefile runtime=C:\Go\pkg\windows_amd64\runtime.a
packagefile errors=C:\Go\pkg\windows_amd64\errors.a
packagefile internal/fmtsort=C:\Go\pkg\windows_amd64\internal\fmtsort.a
packagefile io=C:\Go\pkg\windows_amd64\io.a
packagefile math=C:\Go\pkg\windows_amd64\math.a
packagefile os=C:\Go\pkg\windows_amd64\os.a
packagefile reflect=C:\Go\pkg\windows_amd64\reflect.a
packagefile strconv=C:\Go\pkg\windows_amd64\strconv.a
packagefile sync=C:\Go\pkg\windows_amd64\sync.a
packagefile unicode/utf8=C:\Go\pkg\windows_amd64\unicode\utf8.a
packagefile internal/bytealg=C:\Go\pkg\windows_amd64\internal\bytealg.a
packagefile internal/cpu=C:\Go\pkg\windows_amd64\internal\cpu.a
packagefile runtime/internal/atomic=C:\Go\pkg\windows_amd64\runtime\internal\atomic.a
packagefile runtime/internal/math=C:\Go\pkg\windows_amd64\runtime\internal\math.a
packagefile runtime/internal/sys=C:\Go\pkg\windows_amd64\runtime\internal\sys.a
packagefile internal/reflectlite=C:\Go\pkg\windows_amd64\internal\reflectlite.a
packagefile sort=C:\Go\pkg\windows_amd64\sort.a
packagefile sync/atomic=C:\Go\pkg\windows_amd64\sync\atomic.a
packagefile math/bits=C:\Go\pkg\windows_amd64\math\bits.a
packagefile internal/oserror=C:\Go\pkg\windows_amd64\internal\oserror.a
packagefile internal/poll=C:\Go\pkg\windows_amd64\internal\poll.a
packagefile internal/syscall/execenv=C:\Go\pkg\windows_amd64\internal\syscall\execenv.a
packagefile internal/syscall/windows=C:\Go\pkg\windows_amd64\internal\syscall\windows.a
packagefile internal/testlog=C:\Go\pkg\windows_amd64\internal\testlog.a
packagefile syscall=C:\Go\pkg\windows_amd64\syscall.a
packagefile time=C:\Go\pkg\windows_amd64\time.a
packagefile unicode/utf16=C:\Go\pkg\windows_amd64\unicode\utf16.a
packagefile unicode=C:\Go\pkg\windows_amd64\unicode.a
packagefile internal/race=C:\Go\pkg\windows_amd64\internal\race.a
packagefile internal/syscall/windows/sysdll=C:\Go\pkg\windows_amd64\internal\syscall\windows\sysdll.a
packagefile internal/syscall/windows/registry=C:\Go\pkg\windows_amd64\internal\syscall\windows\registry.a
EOF
mkdir -p $WORK\b001\exe\
cd .
"C:\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "$WORK\\b001\\exe\\helloworld.exe" -importcfg "$WORK\\b001\\importcfg.link" -s -w -buildmode=exe -buildid=O97mupZ1w3kiblxmWDWH/fYUzxKmhHIgbtJYCRI93/451t1_THFAFC5bnaPOQF/O97mupZ1w3kiblxmWDWH -extld=gcc "C:\\Users\\Administrator\\AppData\\Local\\go-build\\13\\1393673cb1fc6a992fd0d9e1e30f237e0b61dfd69337713c72ba8ff94fef9496-d"
$WORK\b001\exe\helloworld.exe

代碼格式化

# vs code IDE 會在保存go 程序是自動格式化代碼,go 也提供了 'go fmt' 命令來格式代碼

go fmt helloworld.go

變量

package main

import "fmt"

func main() {
    
    // var 變量名 類型 = 變量值
    var msg string = "hello world !"
    
    fmt.Println(msg)
}

變量的定義方式

普通定義方式

package main

import (
	"fmt"
)

func main() {

	var initVarValue string = "初始化變量與變量值"

	// 僅初始化變量的類型,未定義變量的值
	// 相當於 python 中的:not_innit_var_value = ""
	var notInitVarValue string

	// 僅初始化值,但不定義變量的類型,讓其根據變量的值(此時變量的值便不能省略)來推導變量的類型
	var notInitVarType = "未定義變量的類型,僅定義了變量的值來推導變量的類型"

	// 短聲明(注意:僅可以在函數級別使用!)
	shortVar := "不用關鍵字`var`,用`:`代替變量的類型"

	fmt.Println(initVarValue)

	fmt.Println(notInitVarValue)

	fmt.Println(notInitVarType)

	fmt.Println(shortVar)

}


/*

初始化變量與變量值

未定義變量的類型,僅定義了變量的值來推導變量的類型
不用關鍵字`var`,用`:`代替變量的類型

*/

相同類型的變量可以合並定義

package main

import "fmt"

func main() {

	/*

		var a string = "最全定義變量的方式"

		var b = "省略變量的類型"

		// 省略變量的初始值(此類型的零值)
		var c string

	*/

	// 此三個相同類型的變量則可以合並定義
	var (
		a string = "最全定義變量的方式"

		b = "省略變量的類型"

		c string
	)

	fmt.Println(a)

	fmt.Println(b)

	fmt.Println(c)

	/*

		d := "短聲明d"

		e := "短聲明e"

	*/

	d, e := "短聲明d", "短聲明e"

	fmt.Println(d)

	fmt.Println(e)

}


/*

最全定義變量的方式
省略變量的類型

短聲明d
短聲明e

*/

變量的作用域

package main

import (
	"fmt"
)

// 包級別的變量
var packageVar = "包級別的變量"

func main() {

	// 函數級別的變量
	var funcVar string = "函數級別的變量"

	fmt.Println(packageVar, funcVar)

	{

		// 塊級別的變量
		var blockVar = "塊級別的變量"

		fmt.Println(packageVar, funcVar, blockVar)

		{
			// 子塊級別的變量
			var innerBlockVar = "子塊級別的變量"

			fmt.Println(packageVar, funcVar, blockVar, innerBlockVar)
		}
        
	}

}


/*

包級別的變量 函數級別的變量
包級別的變量 函數級別的變量 塊級別的變量
包級別的變量 函數級別的變量 塊級別的變量 子塊級別的變量

*/

注意:函數(塊)內定義的變量一定要使用,否則會報錯

package main

import (
	"fmt"
)

// 包級別的變量
var packageVar = "包級別的變量"

func main() {

	// 函數級別的變量
	var funcVar string = "函數級別的變量"

	fmt.Println(packageVar, funcVar)

	{

		// 塊級別的變量
		var blockVar = "塊級別的變量"

		fmt.Println(packageVar, funcVar, blockVar)

		{
			// 子塊級別的變量
			var innerBlockVar = "子塊級別的變量"

			fmt.Println(packageVar, funcVar, blockVar, innerBlockVar)
		}

		// 在塊的外面調用不到塊內的變量
		fmt.Println(innerBlockVar)
	}

}


/* 

# command-line-arguments
.\block.go:32:15: undefined: innerBlockVar

*/

塊即變量的作用域,會限制變量的使用范圍

子塊中若與父塊中有相同的變量,父塊中的變量值會被子塊中的變量值所覆蓋

變量賦值

package main

import "fmt"

func main() {

	var name string = "name變量初識值"

	fmt.Println(name)

	// 給`name`變量重新賦值
	name = "name變量被重新賦值"

	fmt.Println(name)

	{
		name = "name變量在塊中被重新賦值"
	}

	fmt.Println(name)

}


/*

name變量初識值
name變量被重新賦值
name變量在塊中被重新賦值

*/

標識符

概念

就是編程時用於標識的一種符號,具體有:(變量、常量、函數、包、接口等)

命名規則

  1. 構成元素:非空Unicode字符、下划線、數字,但注意不能以數字開頭;
  2. 不能使用go語言中的關鍵字(25個);
    • 聲明:import、package
    • 實體聲明和定義:chan、const、func、interface、map、struct、type、var
    • 流程控制:break、case、continue、default、defer、else、fallthrough、for、go、goto、 if、range、return、select、switch
  3. 避免使用go語言預先設定的一些內置標識符;
    • 內置常量:true、false、nil、iota
    • 內置類型:bool、byte、rune、int、int8、int16、int32、int64、uint、uint8、unit16、 unit32、unit64、uintptr、float32、float64、complex64、complex128、string、error
    • 內置函數:make、len、cap、new、append、copy、close、delete、complex、real、 imag、panic、recover
    • 空白標識符:_
  4. 建議使用駝峰體;
  5. 區分大小寫。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM