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

by Liu Yue/2022-08-03

    前文再续,书接上回,前一篇:兔起鹘落全端涵盖,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就是这个时代的一阳指,内功心法上借鉴了六脉神剑,将内力灌注于指端,亦能隔空伤人,但是入门的门槛更低,就算没有武学基础的小白也可以进行修炼,练成之后,性能和威力却不逊于六脉神剑,具体心法如何,且听下回分解。