初窥门径代码起手,Go lang1.18入门精炼教程,由白丁入鸿儒,首次运行golang程序EP01

835 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

前文再续,书接上回,前一篇:兔起鹘落全端涵盖,Go lang1.18入门精炼教程,由白丁入鸿儒,全平台(Sublime 4)Go lang开发环境搭建EP00,我们搭建起了Go lang1.18的开发运行环境,接着就可以运行第一个Go lang1.18程序了,让我们整装待发,开启Go lang1.18的处女航。

首次运行

打开Sublime 4,在任意目录下新建test.go文件:



package main // 声明 main 包

  
import "fmt" // 导入 fmt 包,打印字符串时需要用到

  
func main() {  // 声明 main 主函数入口

  
	fmt.Println("hello Go lang 1.18") // 打印 字符串

}


随后按快捷键组合 control + b 运行程序 (Mac平台使用cmd + b)

程序返回:

> Environment:  
>   GOPATH=C:/Go  
> Directory: C:\Users\liuyue\www\tornado6  
> Command: C:/Go/bin\go.exe run -v C:\Users\liuyue\www\tornado6\test.go  
> Output:  
command-line-arguments  
hello go1.18  
> Elapsed: 3.070s  
> Result: Success

和Python或者Ruby这些解释型语言不同,Go lang和Java一样,是编译型语言,运行之前需要编译成可执行文件后才能执行,而 go run命令会编译源码,并且直接执行源码的 main() 函数,不会在当前目录留下可执行文件。

可以看到Sublime帮我们执行了go run命令,如果愿意,可以在终端直接执行编译运行命令:

C:\Users\liuyue\www\tornado6>go run test.go  
hello Go lang 1.18

效果是一样的。如果需要单独编译成可执行文件,可以使用go build命令:

C:\Users\liuyue\www\tornado6>go build test.go  
C:\Users\liuyue\www\tornado6>dir  
test.go test.exe

代码解析

首先Go lang支持用//在代码中加一些说明和解释,方便自己或其他程序员阅读代码,能够大大增强程序的可读性:

fmt.Println("Hello,Go lang1.18") // 右边的所有内容当做说明,而不是真正要执行的程序,起辅助说明作用

也支持使用/**/多行注释:

func main() {  
	/*  
		以下代码都是将信息打印在屏幕上  
	 */  
	fmt.Println("Hello Go lang 1.18")  
  
}

go run命令在编译代码时,会忽略注释的内容。如果你写的一些测试代码不想让计算机执行,那么也可以加上注释。

Go lang以package(包)作为模块管理单位,每个 Go lang源文件必须先声明它所属的包,所以我们会看到每个 Go 代码的开头都有一个 package 声明:

package main // 声明 main

Go lang的package与目录是对应的,它具有以下几点特性:

1.一个目录下的同级文件属于同一个package。

2.package名称可以与其所在目录名不同。

3.main 包是 Go lang程序的入口包,一个 Go 语言程序必须有且仅有一个 main 包。如果一个程序没有 main 包,那么编译时将会出错,无法生成可执行文件,这一点沿袭了C语言的特性。

在声明了当前文件的package之后,我们也可以为程序导入需要的工具包,比如:

import "fmt" // 导入 fmt 包,打印字符串时需要用到

这一点和Python类似,你想用什么,就可以import什么,fmt 包是 Go lang 内置的系统标准库。使用它可以格式化输入输出的内容,类似的系统内置包还有 os 、io 等等。

导包的时候还有一些雕虫小技,比如:

import . "fmt" // 导入 fmt 包,打印字符串时需要用到

这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调用的fmt.Println("hello world")可以省略的写成Println("hello world")

和Python类似,包可以自己声明别名:

import f "fmt" // 导入 fmt 包,打印字符串时需要用到

别名操作的话调用包函数时前缀变成了我们的前缀,即f.Println("hello world")。

还可以在导包的时候自动初始化对象:

import _ "github.com/ziutek/mymysql/godrv"

_ 操作是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数。

但需要注意的是,导入的包里面不能含有代码中没有使用到的包,否则 Go 编译器会报编译错误,例如 imported and not used: "os",换句话说,你用到什么就导什么,不用就别导,和自助餐厅里吃多少拿多少的含义是一样的。

和Python类似,Go lang也可以使用一个 import 关键字导入多个包,此时需要用括号( )将包的名字包围起来,并且每个包名占用一行,也就是写成下面的样子:

import(  
    "fmt"  
    "os"  
)

main方法是 Go lang程序的入口方法,有点类似Python中的 if __name__ == '__main__',即程序启动后运行的第一个方法。main方法只能声明在 main 包中,不能声明在其他包中,并且,一个 main 包中也必须有且仅有一个 main 方法。

同时,main方法也是自定义方法的一种,在 Go lang中,所有方法都以关键字 func开头的,定义格式如下所示:

func 函数名 (参数列表) (返回值列表){  
    函数体  
}

需要注意的是,Go lang的写法没有那么随性,左大括号{必须和函数名称在同一行,否则会报错。

fmt.Println()方法是 fmt 包中的一个内置方法,它用来格式化输出数据,比如字符串、整数、小数等。这里我们使用 Println 函数来打印字符串。注意,Println 函数打印完成后会自动换行,ln 是 line 的缩写。

关于GOPATH工作目录

网上很多教程都是基于gopath模式来讲解,gopath目录结构如下

-- bin 存放编译后生成的二进制可执行文件
-- pkg 存放编译后生成的 .a 文件
-- src 存放项目的源代码,可以是你自己写的代码,也可以是你 go get 下载的包

将自己的包或者别人的包全部放在 $GOPATH/src 目录下进行管理的方式,我们称之为 GOPATH 模式。

但事实上是,从 go lang 1.11 开始,go env 多了个环境变量: GO111MODULE ,这里的 111,其实就是 v1.11 的版本标识,GO111MODULE 是一个开关,通过它可以开启或关闭 go mod 模式。

它有三个可选值:off、on、auto,默认值是auto。
GO111MODULE=off ,禁用模块支持,编译时会从GOPATH和vendor文件夹中查找包。
GO111MODULE=on ,启用模块支持,编译时会忽略GOPATH和vendor文件夹,只根据 go.mod下载依赖。
GO111MODULE=auto,当项目在$GOPATH/src外且项目根目录有go.mod文件时,自动开启模块支持。

go mod 出现后,GOPATH 正在被逐步淘汰,基本没人用了。

这也解释了为什么上一篇文章中我们需要手动开启go mod:

go env -w GO111MODULE=on  
go env -w GOPROXY=https://goproxy.cn,direct

如果您是go lang 1.18的初学者,那么就可以忘记GOPATH,完全投入go mod的怀抱,但如果您手头还维护着低版本的go lang项目,那么就应该将GO111MODULE 置为 off。

结语

Go lang 可以被认为是次时代的C语言,进行类比的话,如果说远古时代的C语言是绝世神功六脉神剑,六脉齐发,隔空伤人,性能无敌,但是门槛太高,现代人已经无法修聚到惊世骇俗的内力来催动这种剑气绝学,那么Go lang就是这个时代的一阳指,内功心法上借鉴了六脉神剑,将内力灌注于指端,亦能隔空伤人,但是入门的门槛更低,就算没有武学基础的小白也可以进行修炼,练成之后,性能和威力却不逊于六脉神剑,具体心法如何,且听下回分解。