目录
第一章 go语言起源
第一节 go语言发展
1.知名编程语言或系统的发展简吏
2.Go语言的前世今生
3.go语言的核心特性
4.Go语言的优势和其他语言的对比
5.Go开发环境搭建
第二章 go语言Helloworld
一、go项目工程结构
二、执行go程序
三、go程序的解释说明
第三章 go的执行原理以及go命令
一、go的源码文件
二、Go的命令
1、go run
2、go build
3、go install
4、go get
5、其他命令
第四章 安装Goland开发工具
1.使用goland
2.安装和配置 Visual Studio Code for Go 开发(安装和配置 Visual Studio Code for Go 开发 - Go on Azure | Microsoft Learn)
1.安装 Go
2.安装 Visual Studio Code
3.安装 Go 扩展
4.更新 Go 工具
5.编写示例 Go 程序
6.运行调试器
解决 vscode下载go相关插件失败的问题
附1:go 引用其它文件中的函数
附2:GO 命令教程 (go get · GO 命令教程 · 看云)
附3: 100天精通Golang(基础入门篇)——第3天:Go语言的执行原理及常用命令、编码规范和常用工具 (100天精通Golang(基础入门篇)——第3天:Go语言的执行原理及常用命令、编码规范和常用工具-腾讯云开发者社区-腾讯云)
第一章 go语言起源
第一节 go语言发展
1.知名编程语言或系统的发展简吏
B语言
B语言之父: Ken Thompson(肯.汤普森).
B语言是贝尔实验室开发的一种通用的程序设计语言,该语言得名于汤姆森的妻子Bonnie。
C语言
C语言之父: Dennis Ritchie(丹尼斯.里奇)
美国著名计算机专家、C语言发明人、UNIX之父。在1969-1973年期间发明了C语言和Unix操作系统。
Unix
Unix之父: Dennis Ritchie(丹尼斯.里奇)及 Ken Thompson(肯.汤普森)。在1973年左右发明了Unix操作系统。两人因此获得1983年图灵奖。
C++
C++之父:Bjarne Stroustrup(本贾尼.斯特劳斯特卢普)
1982年,美国贝尔实验室的Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,它被命名为C++。
Python
Python之父: Guido van Rossum(吉多. 范 . 罗苏姆)
1989年,为了打发圣诞节假期,Guido开始写Python语言的编译/解释器。1994年发布1.0版本,1995年9月发布了Python3.5版。
Java
java: James Gosling(詹姆斯.高斯林)
1991年开发Oak, 1994年更名为Java, 1995年5月正式发布。
JavaScript
javascript: Brendan Eich(布兰登. 艾奇)
艾奇对java一点兴趣也没有,为了应会公司安排的任务,他于1995年5月只用了10天时间就把javascript设计出来了。
2.Go语言的前世今生
Go的产生背景
为什么需要一个新的语言
最近十年来, C/C++在计算领域没有很好得到发展,并没有新的系统编程语言出现。对开发程度和系统效率在很多情况下不能兼得。要么执行效率高,但低效的开发和编译,如c++; 要么执行低效,但拥有有效的编译,如.NET、Java;所以需要一种拥有较高效的执行速度、编译速度和开发速度的编程语言,Go就横空出世。
3.go语言的核心特性
并发编程
Go语言在并发编程方面比绝大多数语言要简洁不少,这一点是其最大亮点之一,也是其在未来进入高并发高性能场景的重要筹码。
golang的并发执行单元是一种称为goroutine的协程。
内存回收(GC)
内存自动回收,再也不需开发人员管理内存
开发人员专注业务实现,降低了心智负担
只需要new分配内存,不需要释放。
内存分配
先分配一块大内存区域
大内存被切分成各个大小等级的块,放入不同的空闲list中
对象分配空间时从空闲list中取出大小合适的内存块
内存回收时,会把不用的内存重放回空闲list
空闲内存会按照一定策略合并,以减少碎片。
编译
目前Golang具有两种编译器
一种是建立在GCC基础上的Gccgo
另外一种是分别针对64位x64和32位x86计算机的一套编译器(6g和8g)
网络编程
socket用net.Dial(基于tcp/udp, 封装了传统的connect、listen、accept等接口)
http用http.Get/Post()
rpc用client.Call(‘class_name.method_name’, args, &reply)
函数多返回值
允许函数返回多个值,在某些场景下,可以有效的简化编程
GO语言推荐的编程风格,是函数返回的最后一个参数为error类型(只要逻辑体中可能出现异常),这样,在语言级别支持多返回值,就很有必要了。
语言交互性
语言交互性指的是本语言是否能和其他语言交互,比如可以调用其他语言编译的库。
Go可以和C程序交互
异常处理
3个重要关键字defer、panic、recover
defer是函数结束后执行,呈先进后出;
panic是程序出现无法修复的错误时使用,但会让defer执行完;
recover会修复错误,不至于程序终止,当不确定函数不会出错时使用derfer+recover
其他一些有趣的特性
类型推导
接口interface
defer机制
“包”的概念
交叉编译
4.Go语言的优势和其他语言的对比
1、Go语言设计初衷(zhong)
为了解决当时Google开发遇到的问题
编译慢
大量的C++代码, 同时又引入了java和Python
更新的花费起来越长
分布式的编译系统
数百万的服务器
2、Go语言的特色
高效的并发编程
内存回收(GC)
编译速度快
函数多返回值
语言交互性
没有异常处理(error is value)
5.Go开发环境搭建
https://golang.org (需要翻墙)
Golang的国内网站: The Go Programming Language
下载安装包
解压到指定目录下:
tar -xzf go1.20.3.linux-amd64.tar.gz -C /usr/local
运行 vim /etc/profile.在最下面加入下面两行
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
让环境变量生效 ,
source /etc/profile
运行 :
go version
centos 8.2 配置 go 项目开发环境_爱死亡机器人的技术博客_51CTO博客
Go语言GOPATH详解(Go语言工作目录)
windows下gopath设置 - 爱码网
第二章 go语言Helloworld
一、go项目工程结构
配置好工作目录后, 就可以编码开发了,在这之前,先看下go的通用项目结构,这里的结构主要是源代码相应地资源文件存放目录结构.
1.1 gopath目录
gopath目录就是我们存储所编写源代码的目录。该目录下往往要有3个子目录:src, bin, pkg
src ----里面每一个子目录,就是一个包,包内是Go的源码文件
pkg ---编译后生成的。包的目标文件
bin ---生成的可执行文件
1.2 编写第一个程序
在Home/go的目录 下,(就是GoPath目录里),创建一个目录叫src, 然后再该目录下创建一个文件玩意儿叫hello,在该目录下创建一个文件叫helloworld.go,并双击打开,输入以下内容。
package main
import "fmt"
func main(){
fmt.Println("hello, world")
}
二、执行go程序
执行go程序有以下几种方式:
方式一:使用go run命令
进入终端: windows下使用快捷键win+R,输入cmd打开命令提示符.
linux下可以使用快捷键 ctrl + alt + T
mac下command+空格,输入 termainl
进入helloworld.go所在的目录
输入go run helloworld.go命令并观察运行结果
方式二:使用go build命令
打开终端; 在任意文件路径上,运行 go install hello
也可以进入项目(应用包)的路径,然后运行: go install
注意:在编译生成go程序时,go实际上会去两个地方找程序包:GOROOT下的src文件夹下,以及GOPATH 下的src文件夹下。
在程序包里,自动找main包的main函数作为程序入口,然后进行编译。
运行go程序
在/home/go/bin下(即GOPATH目录下)(如果之前没有bin目录则会自动创建),会发现出现了一个hello的可执行文件,用如下命令运行: ./hello
错误:go.mod file not found in current directory or any parent directory;
开启Go Module Windows:
go env -w GO111MODULE=auto
Mac:
export GO111MODULE=on
然后命令行输入 go env 查看环境变量,GO111MODULE 选项为 on 代表修改成功。
初始化 在你的项目文件夹下,使用GO MODULE进行初始化,下面是我刚刚报错的工程:
执行 go mod init day01 (day01为项目名),在项目根目录会出现一个 go.mod 文件。
注意,此时的 go.mod 文件只标识了项目名和go的版本,这是正常的,因为只是初始化了,所以我执行go run hello.go 跑不起来。根据提示,go get xxx(相关依赖)下载至本地即可。
go module介绍
GO111MODULE=off,无模块支持,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,模块支持,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
1.当前目录在GOPATH/src之外且该目录包含go.mod文件,开启模块支持。
2.当前文件在包含go.mod文件的目录下面。
注:
在使用go modules时,GOPATH是无意义的,不过它还是会把下载的依赖存储在$GOPATH/pkg/mod 中
也会把go install 的结果放在 $GOPATH/bin 中。
当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg
允许同一个package多个版本并存,且多个项目可以共享缓存的module。
三、go程序的解释说明
1.package
在同一个包下面的文件属于同一个工程文件,不用import包,可以直接使用
在同一个包下面的所有文件的package名,都是一样的
在同一个包下面的文件package名都建议设为该目录名,但也可以不是
2.import
import "fmt"告诉Go编译器这个程序需要使用fmt包的函数, fmt包实现了格式化IO(输入/输出)的函数可以是相对路径也可以是绝对路径,推荐使用绝对路径(起始于工程根目录)
1)、点操作
我们有时候会看到如下的方式导入包
import(
."fmt"
)
这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是间面你调用的fmt.Println("hello world") 可以省略的写成Println("hello world")
2)、别名操作
别名操作顾名思义我们可以把包命名成另一个我们用起来容易记忆的名字。
import(
f "fmt"
)
别名操作的话调用包函数时前缀变成了我们的前缀,即f.Println("hello world");
3)、_操作
这个操作经常是让很多人费解的一个操作符,请看下面这个import
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
_操作基实是引入该包,而不直接使用包里面的函数,而是调用了该包里的init函数。
3.main
main()是程序运行的入口。
四、包的说明
源代码都是存放在GOPATH的src目录下,多个项目的时候,怎么区分呢,答案是通过包,使用包来组织项目结构。如java开发一样,包以网站域名开头就不会有重复,包名是唯一的。
如果有自己的域名,那也可以使用自己的域名,如果没有个人域名,现在流行的做法是使用个人的github名,因为每个人的是唯一的,当然也会有重复。
src目录下跟着一个个域名命名的文件夹,再以github.com文件夹为例,它里面有是以github用户名命名的文件玩意儿,用于存储属于这个github用户编写的go源代码。
第三章 go的执行原理以及go命令
一、go的源码文件
1、命令源码文件:(命令源码文件是 Go 程序的入口)
声明自己属于 main 代码包、包含无参数声明和结果声明的 main 函数。
命令源码文件被安装以后,GOPATH 如果只有一个工作区,那么相应的可执行文件会被存放当前工作区的 bin 文件夹下;如果有多个工作区,就会安装到 GOBIN 指向的目录下。
命令源码文件是Go程序的入口.
命令源码文件应该是被单独放在一个代码包中,是可以单独运行的。可以使用 go run 命令直接运行,也可以通过 go build 或 go install 命令得到相应的可执行文件。但是多个命令源码文件虽然可以分开单独 go run 运行起来,但是无法通过 go build 和 go install。所以命令源码文件是可以在机器的任何目录下运行的。
2、库源码文件
库源码文件就是不具备命令源码文件上述两个特征的源码文件。存在于某个代码包中的普通的源码文件。
库源码文件被安装后,相应的归档文件(.a 文件)会被存放到当前工作区的 pkg 的平台相关目录下。
3、测试源码文件
名称以 _test.go 为后缀的代码文件,并且必须包含 Test 或者 Benchmark 名称前缀的函数:
func TestXXX( t *testing.T) {
} 名称以 Test 为名称前缀的函数,只能接受 *testing.T 的参数,这种测试函数是功能测试函数。
func BenchmarkXXX( b *testing.B) {
}
名称以 Benchmark 为名称前缀的函数,只能接受 *testing.B 的参数,这种测试函数是性能测试函数。
举个栗子:
比如平时我们在 LeetCode 上刷算法题,这时候写的就是一个程序,这就是命令源码文件,可以在电脑的任意一个文件夹新建一个 go 文件就可以开始刷题了,写完就可以运行,对比执行结果,答案对了就可以提交代码。
但是公司项目里面的代码就不能这样了,只能存放在 GOPATH 目录下。因为公司项目不可能只有命令源码文件的,肯定是包含库源码文件,甚至包含测试源码文件的。
二、Go的命令
目前Go的最新版本1.20里面基本命令有以下18个。
可以打开终端输入: go help可查看到Go的这些命令以及简介。
Usage:
go <command> [arguments]
The commands are:
bug start a bug report
build compile packages and dependencies
clean remove object files and cached files
doc show documentation for package or symbol
env print Go environment information
fix update packages to use new APIs
fmt gofmt (reformat) package sources
generate generate Go files by processing source
get download and install packages and dependencies
install compile and install packages and dependencies
list list packages or modules
mod module maintenance
work workspace maintenance
run compile and run Go program
test test packages
tool run specified go tool
version print Go version
vet report likely mistakes in packages
Use "go help <command>" for more information about a command.
Additional help topics:
buildconstraint build constraints
buildmode build modes
c calling between Go and C
cache build and test caching
environment environment variables
filetype file types
go.mod the go.mod file
gopath GOPATH environment variable
gopath-get legacy GOPATH go get
goproxy module proxy protocol
importpath import path syntax
modules modules, module versions, and more
module-get module-aware go get
module-auth module authentication using go.sum
packages package lists and patterns
private configuration for downloading non-public code
testflag testing flags
testfunc testing functions
vcs controlling version control with GOVCS
Use "go help <topic>" for more information about that topic.
其中和编译相关的有build、get、install、run这4个,接下来依次查看这四个命令的作用。
在详细介绍这四个命令之前,先罗列一下通用的命令标记,以下这些命令都可适用的。
名称 说明 | |
---|---|
-a 用于强制重新编译所有涉及的Go语言代码包(包括Go语言标准库中的代码包),即使它们已经是最新的 了,该标记可以让我们有机会通过改动底层的代码包做一些实验。 | |
-n 使命令仅打印其执行过程中用到的所有命令,而不去真正执行它们,如果不只想查看或者验证命令的执行过程,而不想改变任何东西,使用它正好合适。 | |
-race 用于检测并报告指定Go语言程序中存在的数据竞争问题,当用Go语言编写并发程序的时候,这是很重要的检测手段之一。 | |
-v 用于打印命令执行过程中涉及的代码包。这一定包括我们指定的目标代码包,并且有时还会包括该代码包直接或间接依赖的那些代码包。这会让你知道哪些代码包被执行过了。 | |
-work 用于打印命令执行时生成和使用的临时工作目录 的名字,且命令执行完成后不删除它,这个目录下的文件可能会对你有用,也可以从侧面了解命令的执行过程,如果不添加此标记,那么临时工作目录会在命令执行完毕前删除。 | |
-x 使命令打印其执行过程中用到的所有命令,并同时执行它们。 | |
1、go run
专门用来运行命令源码文件的命令,注意,这个命令不是用来运行所有Go的源码文件的!
go run命令只能接受一个命令源码文件以及若干个库源码文件(必须同属于main包)作为文件参数,且不能接受测试源码文件,它在执行时会检查源码文件的类型,如果参数中有多个或者没有命令源码文件,那么go run命令就只会打印错误提示信息并退出,而不会继续执行。
这个命令具体干了些什么事情呢?来分析分析,我们先重新创建一个新文件: mytest.go, 并加入以下代码:
package main
import "fmt"
func main(){
fmt.Println("HelloWorld");
fmt.PrintLn("你好, go!");
}
执行go run配合-n
go run -n mytest.go
#
# command-line-arguments
#
mkdir -p $WORK\b001\
cat >$WORK\b001\importcfg << 'EOF' # internal
# import config
packagefile fmt=C:\Users\Administrator\AppData\Local\go-build\6b\6b6754731b574d38b24e90057bc6ceeed681cf4ad4aeac41494c32f5ef2158b5-d
packagefile runtime=C:\Users\Administrator\AppData\Local\go-build\83\8336b2089b6cda64e0eb09bd31812094dea2022de938979926c53c4ce57ceba1-d
EOF
cd D:\study_code\go_study\src\hello
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\compile.exe" -o "$WORK\\b001\\_pkg_.a" -trimpath "$WORK\\b001=>" -p main -complete -buildid UPeovU5hhAuzNy4UNtFw/UPeovU5hhAuzNy4UNtFw -dwarf=false -goversion go1.20.3 -c=4 -D _/D_/study_code/go_study/src/hello -importcfg "$WORK\\b001\\importcfg" -pack "D:\\study_code\\go_study\\src\\hello\\mytest.go"
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\buildid.exe" -w "$WORK\\b001\\_pkg_.a" # internal
cat >$WORK\b001\importcfg.link << 'EOF' # internal
packagefile command-line-arguments=$WORK\b001\_pkg_.a
packagefile fmt=C:\Users\Administrator\AppData\Local\go-build\6b\6b6754731b574d38b24e90057bc6ceeed681cf4ad4aeac41494c32f5ef2158b5-d
packagefile runtime=C:\Users\Administrator\AppData\Local\go-build\83\8336b2089b6cda64e0eb09bd31812094dea2022de938979926c53c4ce57ceba1-d
packagefile errors=C:\Users\Administrator\AppData\Local\go-build\d0\d0a96667916b3dec7cae00b05e3de3219051e41b0dc8aceccee55f2e245d49e3-d
packagefile internal/fmtsort=C:\Users\Administrator\AppData\Local\go-build\cb\cbe7337013b7a0fcbe4a172b74246f14dad37a87f1cdcbf23fc61811c8d99410-d
packagefile io=C:\Users\Administrator\AppData\Local\go-build\97\975a75fcccb98b67b285ed6803b44aada6698c26c589eaddf56a5e5eb724620d-d
packagefile math=C:\Users\Administrator\AppData\Local\go-build\b6\b6103d112c73f5b021001063df8ed869e58125b716363d7c86056c301ef79bec-d
packagefile os=C:\Users\Administrator\AppData\Local\go-build\a6\a6e9c50901bfb3eea15292b742a391b17e944f0df99f1be6893b8140d44313d6-d
packagefile reflect=C:\Users\Administrator\AppData\Local\go-build\74\746b2174da3b11ea4d4d1fc22e9cea5df1296b444af2b3e20e66cd6fdd0160ec-d
packagefile sort=C:\Users\Administrator\AppData\Local\go-build\8e\8eadc0215f01641905a0d5596e815d82831e956c4e26c921ac6203250076b953-d
packagefile strconv=C:\Users\Administrator\AppData\Local\go-build\e9\e94ede53509e370796ded4817d1b7b79e0731cebc5067257483a8d20bdc47a14-d
packagefile sync=C:\Users\Administrator\AppData\Local\go-build\18\1882116daf2c91d06e82c2398af8920baf00e9de4681f164d0a31acd88b5def4-d
packagefile unicode/utf8=C:\Users\Administrator\AppData\Local\go-build\c7\c736af65602fbbe4e2bc6b210bd15012debdab2b56b82ca0f01e4b45a7b9dded-d
packagefile internal/abi=C:\Users\Administrator\AppData\Local\go-build\f4\f481a078b5331256da98442e39e3ed871afc71b0f77705f0010fadcc7732dec0-d
packagefile internal/bytealg=C:\Users\Administrator\AppData\Local\go-build\98\98a8f14f0340a4451c9a4eeb2d4ad287de9c3fd81b495515c72e50c9a8d8a6c8-d
packagefile internal/coverage/rtcov=C:\Users\Administrator\AppData\Local\go-build\d8\d859bd2975a3f4929d836ce96a164dad56df0f382ba0a5155752bbbe34e8ce51-d
packagefile internal/cpu=C:\Users\Administrator\AppData\Local\go-build\04\04403fba21c1f28830aede480b93f660db52f61d8abb1401f34071d0deb4ac84-d
packagefile internal/goarch=C:\Users\Administrator\AppData\Local\go-build\ab\abe3a9621910da1fa083ddc6d617afb7d1c1ad37a4e2fbd8a9d36286fc0b3a44-d
packagefile internal/goexperiment=C:\Users\Administrator\AppData\Local\go-build\a5\a54e6205034dc023181ae592d76a52efa29ebaa41bbbeb29099839ecccbad178-d
packagefile internal/goos=C:\Users\Administrator\AppData\Local\go-build\f1\f16c8261a5ae89a7c9d1c4244dffcc9affb2aadfa90940120e537dbf9a8b95b9-d
packagefile runtime/internal/atomic=C:\Users\Administrator\AppData\Local\go-build\bf\bf07a986d099eb252a6f896c5e0e70c69b385be6db942dd0eb1d453c48b74314-d
packagefile runtime/internal/math=C:\Users\Administrator\AppData\Local\go-build\53\538862994ce03e8879742a530269442e21480d5c978d24de6b31efcc0c482762-d
packagefile runtime/internal/sys=C:\Users\Administrator\AppData\Local\go-build\88\8861c8cfcd34026b21defc386ecc0c3e840adc91a147c45e40f24b528c253480-d
packagefile internal/reflectlite=C:\Users\Administrator\AppData\Local\go-build\9c\9c6967db7ec4197c8d0bbcbb944784fe6ccfa0738b602ff08ab8e9e787c41a0b-d
packagefile math/bits=C:\Users\Administrator\AppData\Local\go-build\55\55aac49c24120089eba90718682ddcfc4b05b46aadb767f8b835b7fe16d274c2-d
packagefile internal/itoa=C:\Users\Administrator\AppData\Local\go-build\cf\cf83466007118a2afc64dbeb66801aac38ac84bd08873fc4e88109183b6571bc-d
packagefile internal/poll=C:\Users\Administrator\AppData\Local\go-build\c3\c34351e1401a98e8f59e57d5bdb1330c011e14385e902c7094119716ca155450-d
packagefile internal/safefilepath=C:\Users\Administrator\AppData\Local\go-build\db\db9aede8329aabbf0656c7126e4bf65fd752bb731212b3a6e73943b9c04e2c7a-d
packagefile internal/syscall/execenv=C:\Users\Administrator\AppData\Local\go-build\ad\ad4cab046bd583d854351b7264b94888a46674bb13fda726a1f24b421cac65a2-d
packagefile internal/syscall/windows=C:\Users\Administrator\AppData\Local\go-build\fe\fe309e3af517f131396415a0830daffefa14d1f75deff41fed55fde8472751dc-d
packagefile internal/testlog=C:\Users\Administrator\AppData\Local\go-build\a6\a6248127f3caa65cd4f20d66358fbdd2863af4101676aca2e31db4ee64d71d8f-d
packagefile io/fs=C:\Users\Administrator\AppData\Local\go-build\b1\b1c63c7bef0a9cdf1c47eb169257c33b29948105521fc54fa9a536b7b368e072-d
packagefile sync/atomic=C:\Users\Administrator\AppData\Local\go-build\2b\2b08ecfdd83a5d45ab98fbba49b53d45135d43a5c39e334527457700b4a0c70c-d
packagefile syscall=C:\Users\Administrator\AppData\Local\go-build\f2\f2cfd2231e126b7b6507ad65ad92917794aef36e85d187254d3cb54ae768e82d-d
packagefile time=C:\Users\Administrator\AppData\Local\go-build\25\25d4036494d51670eb299321c553694e26217a30c66adb7d10bf6faf6dc504bf-d
packagefile unicode/utf16=C:\Users\Administrator\AppData\Local\go-build\4c\4cf62bfc325c4f5d9bd04b0283325db234ad67e3532baaa67480774137ebcb2c-d
packagefile internal/unsafeheader=C:\Users\Administrator\AppData\Local\go-build\ab\ab7e82ccb5d5bf5031ccbbf75b8766fa6f2803d08c0221779fddfcde2eb92220-d
packagefile unicode=C:\Users\Administrator\AppData\Local\go-build\ca\ca17028a7b93fc67aca95b2c2f910b8cf4783d76d6ced282a09172ea5bf07fef-d
packagefile internal/race=C:\Users\Administrator\AppData\Local\go-build\ee\eef2c4d9cd1b8d7c62f226f29568816c4d193fd4ca2070943ee997a21ec45e2a-d
packagefile internal/syscall/windows/sysdll=C:\Users\Administrator\AppData\Local\go-build\aa\aad12ba42f23e8c355b7782a19c385d2257a0975674ea261eccdb77d25a977e6-d
packagefile internal/oserror=C:\Users\Administrator\AppData\Local\go-build\aa\aaffebc849a6cdbd4b6f17e60ebc889a5403bd7b81ee1a0b78f925dccde6447f-d
packagefile path=C:\Users\Administrator\AppData\Local\go-build\7a\7a433da405d5a13c9b357afe778222f38ca92969d8d0cc2f1e61e327867c88cb-d
packagefile internal/syscall/windows/registry=C:\Users\Administrator\AppData\Local\go-build\53\53ecb98f5129a32e8253b208c54076da74eef3f44c177bbabc789abf729117d5-d
modinfo "0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nbuild\t-buildmode=exe\nbuild\t-compiler=gc\nbuild\tCGO_ENABLED=0\nbuild\tGOARCH=amd64\nbuild\tGOOS=windows\nbuild\tGOAMD64=v1\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"
EOF
mkdir -p $WORK\b001\exe\
cd .
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "$WORK\\b001\\exe\\mytest.exe" -importcfg "$WORK\\b001\\importcfg.link" -s -w -buildmode=pie -buildid=19N25wuY_JmlC0eE244A/UPeovU5hhAuzNy4UNtFw/UPeovU5hhAuzNy4UNtFw/19N25wuY_JmlC0eE244A -extld=gcc "$WORK\\b001\\_pkg_.a"
$WORK\b001\exe\mytest.exe
PS D:\study_code\go_study\src\hello> go run -work mytest.go
WORK=C:\Users\ADMINI~1\AppData\Local\Temp\go-build1272587697
# command-line-arguments
.\mytest.go:5:8: undefined: fmt.PrintLn
可以看到,最终go run命令是生成了2个文件,一个是归档文件,一个是可执行文件.
go run命令在第二次执行的时候,如果发现导入的代码包没有发生变化,那么go run不会再次编译这个导入的代码包。直接静态连接进来。
go run -n mytest.go
#
# command-line-arguments
#
mkdir -p $WORK\b001\
cat >$WORK\b001\importcfg << 'EOF' # internal
# import config
packagefile fmt=C:\Users\Administrator\AppData\Local\go-build\6b\6b6754731b574d38b24e90057bc6ceeed681cf4ad4aeac41494c32f5ef2158b5-d
packagefile runtime=C:\Users\Administrator\AppData\Local\go-build\83\8336b2089b6cda64e0eb09bd31812094dea2022de938979926c53c4ce57ceba1-d
EOF
cd D:\study_code\go_study\src\hello
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\compile.exe" -o "$WORK\\b001\\_pkg_.a" -trimpath "$WORK\\b001=>" -p main -complete -buildid UPeovU5hhAuzNy4UNtFw/UPeovU5hhAuzNy4UNtFw -dwarf=false -goversion go1.20.3 -c=4 -D _/D_/study_code/go_study/src/hello -importcfg "$WORK\\b001\\importcfg" -pack "D:\\study_code\\go_study\\src\\hello\\mytest.go"
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\buildid.exe" -w "$WORK\\b001\\_pkg_.a" # internal
cat >$WORK\b001\importcfg.link << 'EOF' # internal
packagefile command-line-arguments=$WORK\b001\_pkg_.a
packagefile fmt=C:\Users\Administrator\AppData\Local\go-build\6b\6b6754731b574d38b24e90057bc6ceeed681cf4ad4aeac41494c32f5ef2158b5-d
packagefile runtime=C:\Users\Administrator\AppData\Local\go-build\83\8336b2089b6cda64e0eb09bd31812094dea2022de938979926c53c4ce57ceba1-d
packagefile errors=C:\Users\Administrator\AppData\Local\go-build\d0\d0a96667916b3dec7cae00b05e3de3219051e41b0dc8aceccee55f2e245d49e3-d
packagefile internal/fmtsort=C:\Users\Administrator\AppData\Local\go-build\cb\cbe7337013b7a0fcbe4a172b74246f14dad37a87f1cdcbf23fc61811c8d99410-d
packagefile io=C:\Users\Administrator\AppData\Local\go-build\97\975a75fcccb98b67b285ed6803b44aada6698c26c589eaddf56a5e5eb724620d-d
packagefile math=C:\Users\Administrator\AppData\Local\go-build\b6\b6103d112c73f5b021001063df8ed869e58125b716363d7c86056c301ef79bec-d
packagefile os=C:\Users\Administrator\AppData\Local\go-build\a6\a6e9c50901bfb3eea15292b742a391b17e944f0df99f1be6893b8140d44313d6-d
packagefile reflect=C:\Users\Administrator\AppData\Local\go-build\74\746b2174da3b11ea4d4d1fc22e9cea5df1296b444af2b3e20e66cd6fdd0160ec-d
packagefile sort=C:\Users\Administrator\AppData\Local\go-build\8e\8eadc0215f01641905a0d5596e815d82831e956c4e26c921ac6203250076b953-d
packagefile strconv=C:\Users\Administrator\AppData\Local\go-build\e9\e94ede53509e370796ded4817d1b7b79e0731cebc5067257483a8d20bdc47a14-d
packagefile sync=C:\Users\Administrator\AppData\Local\go-build\18\1882116daf2c91d06e82c2398af8920baf00e9de4681f164d0a31acd88b5def4-d
packagefile unicode/utf8=C:\Users\Administrator\AppData\Local\go-build\c7\c736af65602fbbe4e2bc6b210bd15012debdab2b56b82ca0f01e4b45a7b9dded-d
packagefile internal/abi=C:\Users\Administrator\AppData\Local\go-build\f4\f481a078b5331256da98442e39e3ed871afc71b0f77705f0010fadcc7732dec0-d
packagefile internal/bytealg=C:\Users\Administrator\AppData\Local\go-build\98\98a8f14f0340a4451c9a4eeb2d4ad287de9c3fd81b495515c72e50c9a8d8a6c8-d
packagefile internal/coverage/rtcov=C:\Users\Administrator\AppData\Local\go-build\d8\d859bd2975a3f4929d836ce96a164dad56df0f382ba0a5155752bbbe34e8ce51-d
packagefile internal/cpu=C:\Users\Administrator\AppData\Local\go-build\04\04403fba21c1f28830aede480b93f660db52f61d8abb1401f34071d0deb4ac84-d
packagefile internal/goarch=C:\Users\Administrator\AppData\Local\go-build\ab\abe3a9621910da1fa083ddc6d617afb7d1c1ad37a4e2fbd8a9d36286fc0b3a44-d
packagefile internal/goexperiment=C:\Users\Administrator\AppData\Local\go-build\a5\a54e6205034dc023181ae592d76a52efa29ebaa41bbbeb29099839ecccbad178-d
packagefile internal/goos=C:\Users\Administrator\AppData\Local\go-build\f1\f16c8261a5ae89a7c9d1c4244dffcc9affb2aadfa90940120e537dbf9a8b95b9-d
packagefile runtime/internal/atomic=C:\Users\Administrator\AppData\Local\go-build\bf\bf07a986d099eb252a6f896c5e0e70c69b385be6db942dd0eb1d453c48b74314-d
packagefile runtime/internal/math=C:\Users\Administrator\AppData\Local\go-build\53\538862994ce03e8879742a530269442e21480d5c978d24de6b31efcc0c482762-d
packagefile runtime/internal/sys=C:\Users\Administrator\AppData\Local\go-build\88\8861c8cfcd34026b21defc386ecc0c3e840adc91a147c45e40f24b528c253480-d
packagefile internal/reflectlite=C:\Users\Administrator\AppData\Local\go-build\9c\9c6967db7ec4197c8d0bbcbb944784fe6ccfa0738b602ff08ab8e9e787c41a0b-d
packagefile math/bits=C:\Users\Administrator\AppData\Local\go-build\55\55aac49c24120089eba90718682ddcfc4b05b46aadb767f8b835b7fe16d274c2-d
packagefile internal/itoa=C:\Users\Administrator\AppData\Local\go-build\cf\cf83466007118a2afc64dbeb66801aac38ac84bd08873fc4e88109183b6571bc-d
packagefile internal/poll=C:\Users\Administrator\AppData\Local\go-build\c3\c34351e1401a98e8f59e57d5bdb1330c011e14385e902c7094119716ca155450-d
packagefile internal/safefilepath=C:\Users\Administrator\AppData\Local\go-build\db\db9aede8329aabbf0656c7126e4bf65fd752bb731212b3a6e73943b9c04e2c7a-d
packagefile internal/syscall/execenv=C:\Users\Administrator\AppData\Local\go-build\ad\ad4cab046bd583d854351b7264b94888a46674bb13fda726a1f24b421cac65a2-d
packagefile internal/syscall/windows=C:\Users\Administrator\AppData\Local\go-build\fe\fe309e3af517f131396415a0830daffefa14d1f75deff41fed55fde8472751dc-d
packagefile internal/testlog=C:\Users\Administrator\AppData\Local\go-build\a6\a6248127f3caa65cd4f20d66358fbdd2863af4101676aca2e31db4ee64d71d8f-d
packagefile io/fs=C:\Users\Administrator\AppData\Local\go-build\b1\b1c63c7bef0a9cdf1c47eb169257c33b29948105521fc54fa9a536b7b368e072-d
packagefile sync/atomic=C:\Users\Administrator\AppData\Local\go-build\2b\2b08ecfdd83a5d45ab98fbba49b53d45135d43a5c39e334527457700b4a0c70c-d
packagefile syscall=C:\Users\Administrator\AppData\Local\go-build\f2\f2cfd2231e126b7b6507ad65ad92917794aef36e85d187254d3cb54ae768e82d-d
packagefile time=C:\Users\Administrator\AppData\Local\go-build\25\25d4036494d51670eb299321c553694e26217a30c66adb7d10bf6faf6dc504bf-d
packagefile unicode/utf16=C:\Users\Administrator\AppData\Local\go-build\4c\4cf62bfc325c4f5d9bd04b0283325db234ad67e3532baaa67480774137ebcb2c-d
packagefile internal/unsafeheader=C:\Users\Administrator\AppData\Local\go-build\ab\ab7e82ccb5d5bf5031ccbbf75b8766fa6f2803d08c0221779fddfcde2eb92220-d
packagefile unicode=C:\Users\Administrator\AppData\Local\go-build\ca\ca17028a7b93fc67aca95b2c2f910b8cf4783d76d6ced282a09172ea5bf07fef-d
packagefile internal/race=C:\Users\Administrator\AppData\Local\go-build\ee\eef2c4d9cd1b8d7c62f226f29568816c4d193fd4ca2070943ee997a21ec45e2a-d
packagefile internal/syscall/windows/sysdll=C:\Users\Administrator\AppData\Local\go-build\aa\aad12ba42f23e8c355b7782a19c385d2257a0975674ea261eccdb77d25a977e6-d
packagefile internal/oserror=C:\Users\Administrator\AppData\Local\go-build\aa\aaffebc849a6cdbd4b6f17e60ebc889a5403bd7b81ee1a0b78f925dccde6447f-d
packagefile path=C:\Users\Administrator\AppData\Local\go-build\7a\7a433da405d5a13c9b357afe778222f38ca92969d8d0cc2f1e61e327867c88cb-d
packagefile internal/syscall/windows/registry=C:\Users\Administrator\AppData\Local\go-build\53\53ecb98f5129a32e8253b208c54076da74eef3f44c177bbabc789abf729117d5-d
modinfo "0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nbuild\t-buildmode=exe\nbuild\t-compiler=gc\nbuild\tCGO_ENABLED=0\nbuild\tGOARCH=amd64\nbuild\tGOOS=windows\nbuild\tGOAMD64=v1\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"
EOF
mkdir -p $WORK\b001\exe\
cd .
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "$WORK\\b001\\exe\\mytest.exe" -importcfg "$WORK\\b001\\importcfg.link" -s -w -buildmode=pie -buildid=19N25wuY_JmlC0eE244A/UPeovU5hhAuzNy4UNtFw/UPeovU5hhAuzNy4UNtFw/19N25wuY_JmlC0eE244A -extld=gcc "$WORK\\b001\\_pkg_.a"
$WORK\b001\exe\mytest.exe
2、go build
go build命令主要是用于测试编译,在包的编译过程中,若有必要,会同时编译与之相关联的包。
1.如果是普通包,当你执行go build命令后,不会产生任何文件。
2.如果是main包,当只执行go build命令后,会在当前目录下生成一个可执行文件,如果需要在$GOPATH/bin目录下生成相应的exe文件,需要执行go install或者使用go build -o 路径/可执行文件.
3.如果某个文件夹下有多个文件,而你只想编译其中某一个文件,可以在go build之后加个文件名,例如 go build a.go; go build命令默认会编译当前目录下的所有go 文件。
4.你也可以指定编译输出的文件名,比如: 我们可以指定go build -o 可执行文件名,默认情况是你的package名(非main包), 或都是第一个源文件的文件名(main包)。
5.go build 会忽略目录下以"_"或者j"."开头的go文件.
6.如果你的源代码针对不同的操作系统需要不同的处理,那么你可以根据不同的操作系统后缀来命名文件。
当代码包中有且公有一个命令源码文件的时候,在文件夹所在目录中执行go build命令,会在该目录下生成一个与目录同名的可执行文件.
PS D:\study_code\go_study\src\hello> dir
目录: D:\study_code\go_study\src\hello
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/4/17 16:36 98 helloworld.go
PS D:\study_code\go_study\src\hello> go build
PS D:\study_code\go_study\src\hello> dir
目录: D:\study_code\go_study\src\hello
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/4/30 11:32 1972224 hello.exe
-a---- 2023/4/17 16:36 98 helloworld.go
PS D:\study_code\go_study\src\hello>
于是在当前目录 直接生成了以当前文件夹为名的要执行文件(在Mac平台下是Unix execurable文件, 在windows平台下是exe文件)
但是这种情况下,如果使用go install命令,如果GOPATH里面只有一个工作区,就会在当前工作区的bin目录下生成相应的可执行文件,如果GOPATH下有多个工作区,则是在GOBIN下生成对应的可执行文件。
go install
在linux下报错:go install hello: open /usr/local/go/bin/hello: permission denied
这个问题是因为go install需要创建bin目录,然后把刚才生成的可执行文件放进去,而目前我们在gopath下还没有bin目录,那么就需要先创建这个文件,而普通用户没有直接创建文件夹的权限,这个和Go语言的命令没有关系,可以加上系统命令sodu来执行这个命令,表示使用管理员的身体执行,然后输入密码,那么就可以创建bin这个文件夹了。
那go build和go install究竟干了些什么?
先来看看go build, go build 用于编译我们指定的源码文件或代码包以及它们的依赖包,但是注意如果用来编译非命令源码文件,即库源码文件,go build执行完是不会产生任何结果的,这种情况下, go build命令只是检查库源码文件的有效性,只会做检查性的编译,而不会输出任何结果文件。
go build编译命令源码文件,则会在该命令的执行目录中生成一个可执行文件。
go build后面不追加目录路径的话,它就把当前目录作为代码包并进行编译,go build命令后面如果跟了代码包导入路径作为参数。那么该代码包及其依赖都会被编译。
go build可使用参数 -n了解执行过程
go build -n
#
# hello
#
mkdir -p $WORK\b001\
cat >$WORK\b001\importcfg << 'EOF' # internal
# import config
packagefile fmt=C:\Users\Administrator\AppData\Local\go-build\6b\6b6754731b574d38b24e90057bc6ceeed681cf4ad4aeac41494c32f5ef2158b5-d
packagefile runtime=C:\Users\Administrator\AppData\Local\go-build\83\8336b2089b6cda64e0eb09bd31812094dea2022de938979926c53c4ce57ceba1-d
EOF
cd D:\study_code\go_study\src\hello
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\compile.exe" -o "$WORK\\b001\\_pkg_.a" -trimpath "$WORK\\b001=>" -p main -complete -buildid WPIiPwpvnHlp4aU8isVF/WPIiPwpvnHlp4aU8isVF -goversion go1.20.3 -c=4 -nolocalimports -importcfg "$WORK\\b001\\importcfg" -pack "D:\\study_code\\go_study\\src\\hello\\helloworld.go"
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\buildid.exe" -w "$WORK\\b001\\_pkg_.a" # internal
cat >$WORK\b001\importcfg.link << 'EOF' # internal
packagefile hello=$WORK\b001\_pkg_.a
packagefile fmt=C:\Users\Administrator\AppData\Local\go-build\6b\6b6754731b574d38b24e90057bc6ceeed681cf4ad4aeac41494c32f5ef2158b5-d
packagefile runtime=C:\Users\Administrator\AppData\Local\go-build\83\8336b2089b6cda64e0eb09bd31812094dea2022de938979926c53c4ce57ceba1-d
packagefile errors=C:\Users\Administrator\AppData\Local\go-build\d0\d0a96667916b3dec7cae00b05e3de3219051e41b0dc8aceccee55f2e245d49e3-d
packagefile internal/fmtsort=C:\Users\Administrator\AppData\Local\go-build\cb\cbe7337013b7a0fcbe4a172b74246f14dad37a87f1cdcbf23fc61811c8d99410-d
packagefile io=C:\Users\Administrator\AppData\Local\go-build\97\975a75fcccb98b67b285ed6803b44aada6698c26c589eaddf56a5e5eb724620d-d
packagefile math=C:\Users\Administrator\AppData\Local\go-build\b6\b6103d112c73f5b021001063df8ed869e58125b716363d7c86056c301ef79bec-d
packagefile os=C:\Users\Administrator\AppData\Local\go-build\a6\a6e9c50901bfb3eea15292b742a391b17e944f0df99f1be6893b8140d44313d6-d
packagefile reflect=C:\Users\Administrator\AppData\Local\go-build\74\746b2174da3b11ea4d4d1fc22e9cea5df1296b444af2b3e20e66cd6fdd0160ec-d
packagefile sort=C:\Users\Administrator\AppData\Local\go-build\8e\8eadc0215f01641905a0d5596e815d82831e956c4e26c921ac6203250076b953-d
packagefile strconv=C:\Users\Administrator\AppData\Local\go-build\e9\e94ede53509e370796ded4817d1b7b79e0731cebc5067257483a8d20bdc47a14-d
packagefile sync=C:\Users\Administrator\AppData\Local\go-build\18\1882116daf2c91d06e82c2398af8920baf00e9de4681f164d0a31acd88b5def4-d
packagefile unicode/utf8=C:\Users\Administrator\AppData\Local\go-build\c7\c736af65602fbbe4e2bc6b210bd15012debdab2b56b82ca0f01e4b45a7b9dded-d
packagefile internal/abi=C:\Users\Administrator\AppData\Local\go-build\f4\f481a078b5331256da98442e39e3ed871afc71b0f77705f0010fadcc7732dec0-d
packagefile internal/bytealg=C:\Users\Administrator\AppData\Local\go-build\98\98a8f14f0340a4451c9a4eeb2d4ad287de9c3fd81b495515c72e50c9a8d8a6c8-d
packagefile internal/coverage/rtcov=C:\Users\Administrator\AppData\Local\go-build\d8\d859bd2975a3f4929d836ce96a164dad56df0f382ba0a5155752bbbe34e8ce51-d
packagefile internal/cpu=C:\Users\Administrator\AppData\Local\go-build\04\04403fba21c1f28830aede480b93f660db52f61d8abb1401f34071d0deb4ac84-d
packagefile internal/goarch=C:\Users\Administrator\AppData\Local\go-build\ab\abe3a9621910da1fa083ddc6d617afb7d1c1ad37a4e2fbd8a9d36286fc0b3a44-d
packagefile internal/goexperiment=C:\Users\Administrator\AppData\Local\go-build\a5\a54e6205034dc023181ae592d76a52efa29ebaa41bbbeb29099839ecccbad178-d
packagefile internal/goos=C:\Users\Administrator\AppData\Local\go-build\f1\f16c8261a5ae89a7c9d1c4244dffcc9affb2aadfa90940120e537dbf9a8b95b9-d
packagefile runtime/internal/atomic=C:\Users\Administrator\AppData\Local\go-build\bf\bf07a986d099eb252a6f896c5e0e70c69b385be6db942dd0eb1d453c48b74314-d
packagefile runtime/internal/math=C:\Users\Administrator\AppData\Local\go-build\53\538862994ce03e8879742a530269442e21480d5c978d24de6b31efcc0c482762-d
packagefile runtime/internal/sys=C:\Users\Administrator\AppData\Local\go-build\88\8861c8cfcd34026b21defc386ecc0c3e840adc91a147c45e40f24b528c253480-d
packagefile internal/reflectlite=C:\Users\Administrator\AppData\Local\go-build\9c\9c6967db7ec4197c8d0bbcbb944784fe6ccfa0738b602ff08ab8e9e787c41a0b-d
packagefile math/bits=C:\Users\Administrator\AppData\Local\go-build\55\55aac49c24120089eba90718682ddcfc4b05b46aadb767f8b835b7fe16d274c2-d
packagefile internal/itoa=C:\Users\Administrator\AppData\Local\go-build\cf\cf83466007118a2afc64dbeb66801aac38ac84bd08873fc4e88109183b6571bc-d
packagefile internal/poll=C:\Users\Administrator\AppData\Local\go-build\c3\c34351e1401a98e8f59e57d5bdb1330c011e14385e902c7094119716ca155450-d
packagefile internal/safefilepath=C:\Users\Administrator\AppData\Local\go-build\db\db9aede8329aabbf0656c7126e4bf65fd752bb731212b3a6e73943b9c04e2c7a-d
packagefile internal/syscall/execenv=C:\Users\Administrator\AppData\Local\go-build\ad\ad4cab046bd583d854351b7264b94888a46674bb13fda726a1f24b421cac65a2-d
packagefile internal/syscall/windows=C:\Users\Administrator\AppData\Local\go-build\fe\fe309e3af517f131396415a0830daffefa14d1f75deff41fed55fde8472751dc-d
packagefile internal/testlog=C:\Users\Administrator\AppData\Local\go-build\a6\a6248127f3caa65cd4f20d66358fbdd2863af4101676aca2e31db4ee64d71d8f-d
packagefile io/fs=C:\Users\Administrator\AppData\Local\go-build\b1\b1c63c7bef0a9cdf1c47eb169257c33b29948105521fc54fa9a536b7b368e072-d
packagefile sync/atomic=C:\Users\Administrator\AppData\Local\go-build\2b\2b08ecfdd83a5d45ab98fbba49b53d45135d43a5c39e334527457700b4a0c70c-d
packagefile syscall=C:\Users\Administrator\AppData\Local\go-build\f2\f2cfd2231e126b7b6507ad65ad92917794aef36e85d187254d3cb54ae768e82d-d
packagefile time=C:\Users\Administrator\AppData\Local\go-build\25\25d4036494d51670eb299321c553694e26217a30c66adb7d10bf6faf6dc504bf-d
packagefile unicode/utf16=C:\Users\Administrator\AppData\Local\go-build\4c\4cf62bfc325c4f5d9bd04b0283325db234ad67e3532baaa67480774137ebcb2c-d
packagefile internal/unsafeheader=C:\Users\Administrator\AppData\Local\go-build\ab\ab7e82ccb5d5bf5031ccbbf75b8766fa6f2803d08c0221779fddfcde2eb92220-d
packagefile unicode=C:\Users\Administrator\AppData\Local\go-build\ca\ca17028a7b93fc67aca95b2c2f910b8cf4783d76d6ced282a09172ea5bf07fef-d
packagefile internal/race=C:\Users\Administrator\AppData\Local\go-build\ee\eef2c4d9cd1b8d7c62f226f29568816c4d193fd4ca2070943ee997a21ec45e2a-d
packagefile internal/syscall/windows/sysdll=C:\Users\Administrator\AppData\Local\go-build\aa\aad12ba42f23e8c355b7782a19c385d2257a0975674ea261eccdb77d25a977e6-d
packagefile internal/oserror=C:\Users\Administrator\AppData\Local\go-build\aa\aaffebc849a6cdbd4b6f17e60ebc889a5403bd7b81ee1a0b78f925dccde6447f-d
packagefile path=C:\Users\Administrator\AppData\Local\go-build\7a\7a433da405d5a13c9b357afe778222f38ca92969d8d0cc2f1e61e327867c88cb-d
packagefile internal/syscall/windows/registry=C:\Users\Administrator\AppData\Local\go-build\53\53ecb98f5129a32e8253b208c54076da74eef3f44c177bbabc789abf729117d5-d
modinfo "0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\thello\nbuild\t-buildmode=exe\nbuild\t-compiler=gc\nbuild\tCGO_ENABLED=0\nbuild\tGOARCH=amd64\nbuild\tGOOS=windows\nbuild\tGOAMD64=v1\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"
EOF
mkdir -p $WORK\b001\exe\
cd .
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\link.exe" -o "$WORK\\b001\\exe\\a.out.exe" -importcfg "$WORK\\b001\\importcfg.link" -buildmode=pie -buildid=WOoy0f9ADY4x0NzCXVqQ/WPIiPwpvnHlp4aU8isVF/WPIiPwpvnHlp4aU8isVF/WOoy0f9ADY4x0NzCXVqQ -extld=gcc "$WORK\\b001\\_pkg_.a"
"D:\\Program Files\\Go\\pkg\\tool\\windows_amd64\\buildid.exe" -w "$WORK\\b001\\exe\\a.out.exe" # internal
mv $WORK\b001\exe\a.out.exe hello.exe
可以看到,执行过程和go run大体相同,唯一不同的就是在最后一步,go run是执行了可执行文件, 但是go build命令,只是把库源码文件编译了一遍,然后把可执行文件移动到了当前目录的文件夹中。
3、go install
go install 命令是用来编译并安装代码包或者源码文件的。
go install 命令在内部实际上分成了两步操作:第一步是生成结果文件(可执行文件或者.a包),第二步会把编译好的结果移到$GOPATH/pkg
或者$GOPATH/bin
。
可执行文件: 一般是 go install 带main函数的go文件产生的,有函数入口,所有可以直接运行。
.a应用包: 一般是 go install 不包含main函数的go文件产生的,没有函数入口,只能被调用。
go install 用于编译并安装指定的代码包及它们的依赖包。当指定的代码包的依赖包还没有被编译和安装时,该命令会先去处理依赖包。与 go build 命令一样,传给 go install 命令的代码包参数应该以导入路径的形式提供。并且,go build 命令的绝大多数标记也都可以用于 实际上,go install 命令只比 go build 命令多做了一件事,即:安装编译后的结果文件到指定目录。
安装代码包会在当前工作区的 pkg 的平台相关目录下生成归档文件(即 .a 文件)。 安装命令源码文件会在当前工作区的 bin 目录(如果 GOPATH 下有多个工作区,就会放在 GOBIN 目录下)生成可执行文件。
同样,go install 命令如果后面不追加任何参数,它会把当前目录作为代码包并安装。这和 go build 命令是完全一样的。
go install 命令后面如果跟了代码包导入路径作为参数,那么该代码包及其依赖都会被安装。
go install 命令后面如果跟了命令源码文件以及相关库源码文件作为参数的话,只有这些文件会被编译并安装。
go install 命令究竟做了些什么呢?
localhost:hello ruby$ go install -n## hello#mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT -goversion go1.12.1 -D "" -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile hello=$WORK/b001/_pkg_.apackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a...EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=FJ6kJTmN9rcWcwLhqfiQ/E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT/FJ6kJTmN9rcWcwLhqfiQ -extld=clang $WORK/b001/_pkg_.a/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internalmkdir -p /usr/local/go/bin/mv $WORK/b001/exe/a.out /usr/local/go/bin/hello
localhost:hello ruby$
前面几步依旧和 go run 、go build 完全一致,只是最后一步的差别,go install 会把命令源码文件安装到当前工作区的 bin 目录(如果 GOPATH 下有多个工作区,就会放在 GOBIN 目录下)。如果是库源码文件,就会被安装到当前工作区的 pkg 的平台相关目录下。
在安装多个库源码文件时有可能遇到如下的问题:
go install:no install location for .go files listed on command line (GOBIN not set)
而且,在我们为环境变量(GOBIN)设置了正确的值之后,这个错误提示信息仍然会出现,这是因为,只有在安装命令源码文件的时候,命令程序才会将环境变量GOBIN的值作为结果文件的存放目录。而在安装库源码文件时,在命令程序内部的代表结果文件存放在目录路径的那个变量不会被赋值,最后,命令程序会发现它依然是个无效的空值,所以,命令程序会同样返回一个关于“无安装位置”的错误,这就引出一个结论,我们只能使用安装代码包的方式来安装库源码文件,而不能在go install命令罗列并安装它们,另外, go install 命令目前无法接受标记-o 以自定义结果文件的存放位置,这也从侧面说明了 go install 命令不支持针对库源码文件的安装操作。
4、go get
go get 命令用于从远程代码仓库(比如 Github )上下载并安装代码包。注意,go get 命令会把当前的代码包下载到 $GOPATH 中的第一个工作区的 src 目录中,并安装。
使用 go get 下载第三方包的时候,依旧会下载到 $GOPATH 的第一个工作空间,而非 vendor 目录。当前工作链中并没有真正意义上的包依赖管理,不过好在有不少第三方工具可选。
如果在 go get 下载过程中加入-d
标记,那么下载操作只会执行下载动作,而不执行安装动作。比如有些非常特殊的代码包在安装过程中需要有特殊的处理,所以我们需要先下载下来,所以就会用到-d
标记。
还有一个很有用的标记是-u
标记,加上它可以利用网络来更新已有的代码包及其依赖包。如果已经下载过一个代码包,但是这个代码包又有更新了,那么这时候可以直接用-u
标记来更新本地的对应的代码包。如果不加这个-u
标记,执行 go get 一个已有的代码包,会发现命令什么都不执行。只有加了-u
标记,命令会去执行 git pull 命令拉取最新的代码包的最新版本,下载并安装。
命令 go get 还有一个很值得称道的功能——智能下载。在使用它检出或更新代码包之后,它会寻找与本地已安装 Go 语言的版本号相对应的标签(tag)或分支(branch)。比如,本机安装 Go 语言的版本是1.x,那么 go get 命令会在该代码包的远程仓库中寻找名为 “go1” 的标签或者分支。如果找到指定的标签或者分支,则将本地代码包的版本切换到此标签或者分支。如果没有找到指定的标签或者分支,则将本地代码包的版本切换到主干的最新版本。
go get 常用的一些标记如下:
标记名称 | 标记描述 |
---|---|
-d | 让命令程序只执行下载动作,而不执行安装动作。 |
-f | 仅在使用-u 标记时才有效。该标记会让命令程序忽略掉对已下载代码包的导入路径的检查。如果下载并安装的代码包所属的项目是你从别人那里 Fork 过来的,那么这样做就尤为重要了。 |
-fix | 让命令程序在下载代码包后先执行修正动作,而后再进行编译和安装。 |
-insecure | 允许命令程序使用非安全的 scheme(如 HTTP )去下载指定的代码包。如果你用的代码仓库(如公司内部的 Gitlab )没有HTTPS 支持,可以添加此标记。请在确定安全的情况下使用它。 |
-t | 让命令程序同时下载并安装指定的代码包中的测试源码文件中依赖的代码包。 |
-u | 让命令利用网络来更新已有代码包及其依赖包。默认情况下,该命令只会从网络上下载本地不存在的代码包,而不会更新已有的代码包。 |
go get 命令究竟做了些什么呢?我们还是来打印一下每一步的执行过程。
localhost:hello ruby$ go get -x github.com/go-errors/errors
cd .
git clone https://github.com/go-errors/errors /Users/ruby/go/src/github.com/go-errors/errors
cd /Users/ruby/go/src/github.com/go-errors/errors
git submodule update --init --recursive
cd /Users/ruby/go/src/github.com/go-errors/errors
git show-refcd /Users/ruby/go/src/github.com/go-errors/errors
git submodule update --init --recursive
WORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build188558329
localhost:hello ruby$
详见:初探 Go 的编译命令执行过程
这里可以很明显的看到,执行完 go get 命令以后,会调用 git clone 方法下载源码,并编译,最终会把库源码文件编译成归档文件安装到 pkg 对应的相关平台目录下。
总结一下如下图:
5、其他命令
go clean
go clean 命令是用来移除当前源码包里面编译生成的文件,这些文件包括
-
_obj/ 旧的object目录,由Makefiles遗留
-
_test/ 旧的test目录,由Makefiles遗留
-
_testmain.go 旧的gotest文件,由Makefiles遗留
-
test.out 旧的test记录,由Makefiles遗留
-
build.out 旧的test记录,由Makefiles遗留
-
*.[568ao] object文件,由Makefiles遗留
-
DIR(.exe) 由 go build 产生
-
DIR.test(.exe) 由 go test -c 产生
-
MAINFILE(.exe) 由 go build MAINFILE.go产生
go fmt
go fmt 命令主要是用来帮你格式化所写好的代码文件。
比如我们写了一个格式很糟糕的 test.go 文件,我们只需要使用 fmt go test.go 命令,就可以让go帮我们格式化我们的代码文件。但是我们一般很少使用这个命令,因为我们的开发工具一般都带有保存时自动格式化功能,这个功能底层其实就是调用了 go fmt 命令而已。
使用go fmt命令,更多时候是用gofmt,而且需要参数-w,否则格式化结果不会写入文件。gofmt -w src,可以格式化整个项目。
go test
go test 命令,会自动读取源码目录下面名为*_test.go的文件,生成并运行测试用的可执行文件。默认的情况下,不需要任何的参数,它会自动把你源码包下面所有test文件测试完毕,当然你也可以带上参数,详情请参考go help testflag
go doc
go doc 命令其实就是一个很强大的文档工具。
如何查看相应package的文档呢? 例如builtin包,那么执行go doc builtin;如果是http包,那么执行go doc net/http;查看某一个包里面的函数,那么执行go doc fmt Printf;也可以查看相应的代码,执行go doc -src fmt Printf;
# 查看net/http包
localhost:hello ruby$ go doc net/http
# 查看time包
localhost:hello ruby$ go doc time
# 查看某个包里的指定函数
localhost:hello ruby$ go doc fmt Printf
通过命令在命令行执行 go doc -http=:端口号,比如godoc -http=:8080。然后在浏览器中打开127.0.0.1:8080,你将会看到一个golang.org的本地copy版本,通过它你可以查询pkg文档等其它内容。如果你设置了GOPATH,在pkg分类下,不但会列出标准包的文档,还会列出你本地GOPATH中所有项目的相关文档,这对于经常被限制访问的用户来说是一个不错的选择。
localhost:hello ruby$ godoc -http=:9527
go fix 用来修复以前老版本的代码到新版本,例如go1之前老版本的代码转化到go1
go version 查看go当前的版本
go env 查看当前go的环境变量
go list 列出当前全部安装的package
第四章 安装Goland开发工具
开发工具: 文体类的编辑器: 记事本, notepad, sublime text, atom... 通过命令执行程序
IED: 集成开发环境 (integrated development environment) golang
1.使用goland
Goland是jetBrains公司推出的Go语言IDE,是一款功能强大,使用便捷的产品。下载地址https://www.jetbrains.com/go/
2.安装和配置 Visual Studio Code for Go 开发(安装和配置 Visual Studio Code for Go 开发 - Go on Azure | Microsoft Learn)
本文内容1.安装 Go2.安装 Visual Studio Code3.安装 Go 扩展4.更新 Go 工具5.编写示例 Go 程序6.运行调试器后续步骤显示较少选项
在本快速入门中,你将安装 Go 编译器和工具,安装 Visual Studio Code 以编写 Go 代码,并安装 Go for Visual Studio Code 扩展,该扩展在编写 Go 时提供支持。 配置后,你将创建一个应用程序,运行它,并使用调试工具暂停执行并观察变量的值。
1.安装 Go
从官方页面安装 Go。 这会安装编译器、标准库和许多工具,用于在 Go 开发过程中执行各种常见任务。 若要安装 Go,请执行以下步骤:
-
在 Web 浏览器中,转到 go.dev/doc/install。
-
下载操作系统的版本。
-
下载后,运行安装程序。
-
打开命令提示符,然后运行
go version
以确认已安装 Go。
2.安装 Visual Studio Code
接下来,安装 Visual Studio Code,它提供基本代码编辑功能。 按照以下步骤安装 Visual Studio Code:
-
打开 Web 浏览器并转到 code.visualstudio.com。
-
下载操作系统的版本。 Visual Studio Code 支持 Windows、Linux 和 macOS。
-
下载后,运行安装程序。
3.安装 Go 扩展
安装和配置 Go for Visual Studio Code 扩展。 Visual Studio Code 和 Go 扩展提供 IntelliSense、代码导航和高级调试。
展开表
说明 | 屏幕快照 |
---|---|
在 Visual Studio Code 中,通过单击活动栏中的“扩展”图标来显示“扩展”视图。 或使用键盘快捷方式(Ctrl+Shift+X)。 | |
搜索 Go 扩展,然后选择“安装”。 |
4.更新 Go 工具
展开表
说明 | 屏幕快照 |
---|---|
在 Visual Studio Code 中,打开命令面板的“帮助>显示所有命令”。 或使用键盘快捷方式(Ctrl+Shift+P) | |
Go: Install/Update tools 搜索然后从托盘运行命令 | |
出现提示时,选择所有可用的 Go 工具,然后选择“确定”。 | |
等待 Go 工具完成更新。 |
5.编写示例 Go 程序
在此步骤中,你将编写并运行示例 Go 程序,以确保一切正常运行。
展开表
说明 | 屏幕快照 |
---|---|
在 Visual Studio Code 中,打开 Go 应用程序的根目录。 若要打开文件夹,请在活动栏中选择资源管理器图标,然后选择“ 打开文件夹”。 | |
在资源管理器面板中选择“ 新建文件夹” ,然后为名为的示例 Go 应用程序创建根控制器 sample-app | |
在资源管理器面板中选择“ 新建文件 ”,然后为该文件命名 main.go | |
打开终端“终端新终端”,然后运行以下命令go mod init sample-app 以初始化>示例 Go 应用。 | |
将以下代码复制到 main.go 文件中。 |
示例代码:
Go复制
package main
import "fmt"
func main() {
name := "Go Developers"
fmt.Println("Azure for", name)
}
6.运行调试器
最后,创建一个断点,并使用调试器工具逐行执行代码行,并在暂停应用程序时查看变量中存储的值。
展开表
说明 | 屏幕快照 |
---|---|
单击编号行左侧,在第 7 行上创建断点。 (可选)将光标置于第 7 行并点击 F9。 | |
在 Visual Studio Code 左侧的活动栏中选择调试图标,打开“调试”视图。 (可选)使用键盘快捷方式(Ctrl+Shift+D)。 | |
选择“ 运行和调试”,或选择 F5 运行调试器。 然后将鼠标悬停在第 7 行上的变量 name 上以查看其值。 单击调试器栏上的“继续”或点击 F5 退出调试器。 |
解决 vscode下载go相关插件失败的问题
很多初学者使用vscode的时候,出现最多的问题就是插件安装失败的问题,而插件安装失败最多的问题就是下载失败,本文主要解决go插件安装失败的问题
因为一般go是插件都是国外网站上的,我们国内很多时候是下载不下来的,因此可以使用一个代理去访问,只需要在安装go的机器上执行下面这两条命令
go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.io,direct 第一个命令是开启go的模块管理功能,这是go新引入的一种包管理方式,是基于go.mod文件的,现在新项目都采用这种模式,也就是主流
第二个命令是给GO设置一个代码服务器,下载go的安装包的时候会通过这个代理服务器,就不会有下载不下来的问题了。
一些开源的go框架,比如gin,原来是下载不下来的,使用代理之后就可以下载下来了
完美解决问题 ————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:解决 vscode下载go相关插件失败的问题_go div安装失败-CSDN博客
使用go mod 代理来安装
https://goproxy.io是一个国内的代理
执行
# 旧版,已废弃
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct
# 新版改成如下链接
go env -w GO111MODULE=on
go env -w GOPROXY=https://proxy.golang.com.cn,direct
关闭vscode重新打开,再次点击install all。
附1:go 引用其它文件中的函数
在Go语言中,如果你想在一个文件中引用另一个文件中定义的函数,你可以通过以下几种方式来实现:
-
使用
import/export
机制:Go语言使用关键字package
来组织代码,并通过import
关键字来引入其他package的函数或者变量。如果你想在当前package中引用另一个package的函数,你需要首先通过import
语句将其导入,然后使用函数名来调用它。 -
、、
-
、、
-
使用全局函数:Go语言允许你定义全局函数,这些函数不属于任何package,但可以在所有packages中直接调用。
-
使用init函数:Go语言中的
init
函数是一个特殊的函数,当包被导入时,init
函数会自动被调用。你可以利用这个特性来在导入某个package时执行一些特定的操作。
以下是一些示例代码:
-
使用
import/export
机制:
// file1.gopackage main import "fmt" func printHello() { fmt.Println("Hello")} // file2.gopackage main import "your_package_path/file1" func main() { file1.printHello() // 调用file1.go中定义的函数}
-
使用全局函数:
// file1.gopackage main import "fmt" func printHello() { fmt.Println("Hello")} // file2.gopackage main func main() { printHello() // 调用file1.go中定义的全局函数}
-
使用init函数:
// file1.gopackage main import "fmt" var greeting string func init() { greeting = "Hello"} func printGreeting() { fmt.Println(greeting)} // file2.gopackage main func main() { printGreeting() // 调用file1.go中定义的函数}
在这些示例中,我们定义了一些函数,并在不同的文件中进行了引用。在第一个例子中,我们使用了import/export
机制来引用file1.go
中定义的函数,在第二个例子中,我们使用了全局函数,在第三个例子中,我们使用了init
函数来初始化变量。在实际应用中,你可以根据具体情况选择最合适的方法来引用其他文件中的函数。
附2:GO 命令教程 (go get · GO 命令教程 · 看云)
附3: 100天精通Golang(基础入门篇)——第3天:Go语言的执行原理及常用命令、编码规范和常用工具 (100天精通Golang(基础入门篇)——第3天:Go语言的执行原理及常用命令、编码规范和常用工具-腾讯云开发者社区-腾讯云)
http://idea.iblue.me