目录
- 一.版本选择
- 二.环境准备
- 三.工具的选择
- 四.第一个 hello go
- 4.1 开发
- 4.2 编译
- 4.3 编译+运行
- 4.4 直接安装
- 五.用 go 快速搭建 webserver
- 六.调用外部三方方法
- 七.go vs java 的执行
前言
专栏旨在利用现有的 java 体系内容去完成 go 语言的学习.
本次行文是在 https://go.dev/doc/tutorial/getting-started 官网的手册实操以及结合 java 现有的知识内容做的记录.
一.版本选择
行文时. go 的版本已经到 1.22 .并且仍然保持每年两个版本的更新节奏.
go release version 记录:https://go.dev/doc/devel/release
学习的版本我们参考最近的几个大版本更新.
Go 1.16(2021年)
嵌入文件支持:允许将文本或二进制文件作为资源嵌入到可执行文件中.
默认启用模块:Go modules成为默认的依赖管理方式,不再需要设置环境变量.
Go 1.18(2022年)
泛型支持:引入了泛型,这是一个里程碑式的更新,允许编写更加通用的代码.
性能与工具链优化:持续的性能改进和工具链的更新,如更好的错误信息和调试支持.
从版本更新功能上看,在 1.18 版本更新了泛型功能.从语言角度来说是一次比较大的更新.从这个角度我们尽可能的去选择最新的版本.我这里选择的是 1.19 版本.
版本兼容性的问题?
Go语言的设计哲学之一是强调版本间的兼容性,特别是 Go 1 发布之后,官方引入了Go 1兼容性承诺,保证了Go 1之后的所有版本> (如Go 1.1, Go 1.2, … Go 1.x )在语言规范、库接口以及编译器行为上向后兼容.这意味着,理论上,任何遵循Go 1规范编写的代码应该能在任何 Go 1.x 版本上无修改地编译和运行.这一点对于维护大型代码库和依赖众多第三方库的项目尤为重要.
尽管如此,在Go的发展过程中,还是存在一些需要注意的兼容性细节,尤其是在大版本更新时:
- 标准库变更:虽然核心语言特性和库接口承诺保持稳定,但在某些情况下,标准库中的函数、方法或类型可能会被弃用,或者新增功能.开发者在升级 Go 版本时,应检查是否有使用到已被弃用的 API ,并按照官方建议进行替换.这一点其实不仅仅是 Go ,其他语言也是一样.替换后尽量做好功能回归和监控.
- 工具链变化:Go的工具链(如go fmt, go vet, go test等)和链接器在新版本中可能会有所改进或增加新功能,虽然这些改动通常不会影响已有代码的构建,但有时可能需要调整构建流程或工具配置.
- 平台和操作系统支持:随着时间推移, Go 可能会停止对某些旧的操作系统或架构的支持,这要求在这些平台上运行 Go 应用时可能需要维持使用特定版本的 Go .
- Cgo 和其他外部依赖:如果项目依赖于 Cgo 或其他外部库,升级 Go 版本时需要确保这些依赖也兼容新版本的 Go 环境.
- 性能差异:虽然不是直接的兼容性问题,但不同版本的 Go 在编译器优化和垃圾回收算法等方面的改进,可能导致相同代码在不同版本上的运行性能有所不同.
为了确保升级过程中的兼容性,推荐采取以下措施:- 在升级 Go 版本前,仔细阅读该版本的发布说明,了解所有的更改点.
- 使用 go mod 管理依赖,确保依赖项也与新版本 Go 兼容.
- 在隔离环境中测试升级后的代码,可以是通过虚拟机、 Docker 容器或其他隔离机制,确保所有测试通过后再全面迁移.
- 监控生产环境中的性能指标,确认升级后没有引入意外的性能下降.
- 编译器兼容问题
二.环境准备
以 mac 环境为例.
mac 安装比较简单.如下命令直接安装最新版本
brew install go
安装指定版本
brew install go@1.22
如果要更新到最新版本
brew upgrade go
之前安装了了 1.19.2
go version
brew unlink go
brew link go@1.19
三.工具的选择
常见的 go 开发工具 goland , visual studio , idea .基本是都能满足日常的要求. 其中 goland ,idea 都是需要收费的.但是有你懂得的方法.想知道的可以后台摸我.有钱的尊重知识产权的大佬请直接购买无限制版.开源免费的可以直接使用 visual studio .
当然如果你原来开发 java 就是 idea.那么我还是比较推荐 idea 的.快捷键都是一样.直接无痕切换.丝滑无比.如下是各 ide 的下载直接地址.
idea: https://www.jetbrains.com/zh-cn/idea/download
visual studio :https://code.visualstudio.com/Download需要继续按照 go tools .具体可以直接 guge.摸我
goland :https://www.jetbrains.com/go/download
四.第一个 hello go
4.1 开发
package mainimport "fmt"func main() {fmt.Print("hello go")
}
4.2 编译
go build hellogo.go
编译成功后直接在当前代码所在根目录生成 hellogo 文件
4.3 编译+运行
go run hellogo.go
4.4 直接安装
直接安装后可以在mac 的 bin 目录下直接生成执行程序,这样当前的环境所有目录就可以直接运行了.
go install hellogo.go
Go语言中,源代码文件经过编译后会生成可执行文件.可执行文件的文件类型与操作系统相关.
在Windows操作系统上,可执行文件的文件类型是.exe.
在Linux和Unix操作系统上,可执行文件的文件类型是无后缀的二进制文件.
例如,如果你在Windows上编译一个名为hello.go的Go源代码文件,你将得到一个名为hello.exe的可执行文件.在Linux上编译同样的源代码文件,你将得到一个名为hello的可执行文件.
需要注意的是,Go语言也支持交叉编译,即在一种操作系统上编译生成另一种操作系统的可执行文件.例如,在Windows上可以编译生成Linux环境下可执行文件,反之亦然.所以在交叉编译的情况下,生成的可执行文件的文件类型也与目标操作系统相关.
五.用 go 快速搭建 webserver
作为一个 java 过来人.现在利用 springboot java 里面搭建一个 web 应用程序已经非常方便了.不需要单独去下载 web 容器 汤姆凯特. 也不用到处去配置 web.xml.
仅仅用 @SpringBootApplication 注解+maven tomcat 插件自动就能启动 web 应用服务了.但是如下的几行 go 的代码就能搭建一个完整的 web 容器服务还是令我惊叹.
这也太简单了.这里一切要归功 net/http 的三方包的能力.
package mainimport ("fmt"_ "fmt""net/http"_ "net/http"
)func main() {http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {fmt.Fprint(writer, "web hello go")})err := http.ListenAndServe(":8880", nil)if err != nil {return}}
访问
http://127.0.0.1:8880/
六.调用外部三方方法
- code
package mainimport "fmt"
import "rsc.io/quote"func main() {fmt.Println("hello go start")fmt.Println(quote.Hello())fmt.Println(quote.Go())fmt.Println("hello go end")
}
- 遇到的问题
- cannot find package “rsc.io/quote” 需要 init module.
go mod init hello
download rsc.io/qutoe 包.
go mod tidy
Don’t communicate by sharing memory, share memory by communicating.
不要共享内存来通信,而是通过通信来进行共享内存.
检索了一下发现这个大概是 go 语言大佬的至理名言.难不成我刚刚学习就被上课了?
这段代码主要是演示了 go 在执行外部三方过程的一些问题和执行.后续还有 go module 相关的内容.
七.go vs java 的执行
我们已经知道了 java 是解释执行的语言.他的 slogan 是一次编写到处运行(write once ,run anywhere).具体是通过 jvm (java virtual machine)来扮演的中间解释执行的角色.
相比之下在传统的编程语言中,比如C、C++,当程序被编译时,它们会被转换成特定底层硬件能够理解的代码.因此,如果我们尝试在另一台使用不同硬件的机器上运行相同的代码,
这台机器所理解的代码就会导致错误,所以你必须重新编译代码,使其能够被新硬件所理解.在这个背景下诞生了 java 的解释执行的方式,随之而来的则是被反复提及的解释执行的效率问题.
相比之下 Go 的编译过程省去了中间字节码的步骤.会直接编译为对应操作系统二进制文件.那问题来了 编译后的 到底是什么文件呢?
Go语言的编译过程可以分为三个主要步骤:词法分析、语法分析和代码生成.
词法分析(Lexical Analysis):编译器首先会将源代码文件转换为一系列的词法单元(tokens).词法单元是源代码中具有独立意义的最小单位,如关键字、标识符、运算符、常量等.词法分析器会根据事先定义好的词法规则,将源代码文件分割成一个个的词法单元.
语法分析(Syntax Analysis):词法分析器生成的词法单元序列会被传递给语法分析器,它会根据语法规则构建一个抽象语法树(Abstract Syntax Tree,AST).抽象语法树是一种以树状结构表示源代码结构的数据结构.语法分析器会根据语法规则验证源代码的语法正确性,并生成抽象语法树.
代码生成:一旦抽象语法树构建完成,编译器会根据抽象语法树生成目标代码.目标代码可以是机器码,也可以是字节码或中间代码,这取决于具体的编译器实现和编译目标.在Go语言中,编译器会将抽象语法树转换为平台相关的机器码,并将其保存到目标文件中.
最终,编译器会将所有源代码文件编译为目标文件,然后将目标文件链接成可执行文件或库文件.编译过程中还会进行一些优化措施,如常量折叠、无用代码消除等,以提高生成的代码的性能和效率.
Go 编译过程 #:https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-compile-intro/ 感觉说的挺好.可以移步
赠人玫瑰 手有余香 我是柏修 一名持续更新的晚熟程序员
期待您的点赞,关注加收藏,加个关注不迷路,感谢
您的鼓励是我更新的最大动力
↓↓↓↓↓↓