网站服务器怎么打开,seo博客网址,如何查公司名字是否被注册,wordpress一键搭建脚本大家好#xff0c;这是我给大家准备的新的一期专栏#xff0c;专门讲golang#xff0c;从入门到精通各种框架和中间件#xff0c;工具类库#xff0c;希望对go有兴趣的同学可以订阅此专栏。
go基础 。 Go文件名#xff1a; 所有的go源码都是以 .go 结尾这是我给大家准备的新的一期专栏专门讲golang从入门到精通各种框架和中间件工具类库希望对go有兴趣的同学可以订阅此专栏。
go基础 。 Go文件名 所有的go源码都是以 .go 结尾不过我们有时候为了支持多平台多版本或者在不同的平台CPU下做不同的逻辑处理我们对go的文件名的命名方式又有一些要求 1、平台区分 文件名_平台。 例 file_windows.go, file_unix.go 可选为windows, unix, posix, android, bsd, solaris, linux等 2、测试单元 文件名test.go或者 文件名平台_test.go。 例 path_test.go, path_windows_test.go 3、版本区分(猜测) 文件名_版本号等。 例point_windows_1.4.go 4、CPU类型区分, 汇编用的多 文件名_(平台:可选)_CPU类型. 例point_linux_amd64.go 可选amd64, none, 386, arm, arm64, x86等。 Go语言命名和关键字
1.Go的函数、变量、常量、自定义类型、包(package)的命名方式遵循以下规则 1首字符可以是任意的Unicode字符或者下划线2剩余字符可以是Unicode字符、下划线、数字3字符长度不限
2.Go只有25个关键字 break default func interface selectcase defer go map structchan else goto package switchconst fallthrough if range typecontinue for import return var
3.Go还有37个保留字 Constants: true false iota nilTypes: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptrfloat32 float64 complex128 complex64bool byte rune string errorFunctions: make len cap new append copy close deletecomplex real imagpanic recover
Go语言声明
go有四种主要声明方式 var声明变量, const声明常量, type声明类型 ,func声明函数。
Go的程序是保存在多个.go文件中文件的第一行就是 package包名 声明用来说明该文件属于哪个包(package)package声明下来就是import声明再下来是类型变量常量函数的声明。 go是使用包来组织源代码的包是多个go源码的集合是一种高级的代码复用方案。golang为我们提供了很多内置的包如 fmt、os、io 等。 任何源代码文件必须属于某个包同时源码文件的第一行有效代码必须是package pacakgeName 语句通过该语句声明自己所在的包。 正如我们上一篇文章写的最简单的hello world程序输出一样
package mainimport fmt
func main(){fmt.Println(hello world)
} 我们在文件的最开始是通过package main的方式来说明该文件属于main包接下来我们需要知道包是什么怎么使用它其实学过java或者python等语言的对包的概念和使用并不陌生
包的基本概念 Go 的包借助了目录树组织形式一般包的名称就是其源文件所在的目录虽然Go语言没有强制要求包名必须和其所在的目录名同名但还是建议包名和所在目录同名这样结构更清晰。
包可以定义在很深的目录中包名的定义是不包括目录路径的但是包在引用时一般使用全路径引用。比如在GOPATH/src/a/b/ 下定义一个包 c。在包 c 的源码中只需声明为package c而不是声明为package a/b/c但是在导入 c 包时需要带上路径例如import “a/b/c”。
包的习惯用法 包名一般是小写的使用一个简短且有意义的名称。包名一般要和所在的目录同名也可以不同包名中不能包含- 等特殊符号。包一般使用域名作为目录名称这样能保证包名的唯一性比如 GitHub 项目的包一般会放到GOPATH/src/github.com/userName/projectName 目录下。包名为 main 的包为应用程序的入口包编译不包含 main 包的源码文件时不会得到可执行文件。一个文件夹下的所有源码文件只能属于同一个包同样属于同一个包的源码文件不能放在多个文件夹下。 包的导入
要在代码中引用其他包的内容需要使用 import 导入使用的包。具体语法如下 import 包的路径注意事项
import 导入语句通常放在源码文件开头包声明语句的下面导入的包名需要使用双引号包裹起来包名是从GOPATH/src/ 后开始计算的使用/ 进行路径分隔。
包的导入有两种写法分别是单行导入和多行导入。
单行导入 import package1
import package2多行导入 import (package1package2
)在使用习惯和代码的可读性上我们都习惯于使用多行导入更方便于我们管理使用。 包的导入路径
包的引用路径有两种写法分别是全路径导入和相对路径导入
包的引用格式
包的引用有四种格式下面以 fmt 包为例来分别演示一下这四种格式。
1) 标准引用格式 import fmt此时可以用fmt.作为前缀来使用 fmt 包中的方法这是常用的一种方式。
示例代码如下 package main
import fmt
func main() {fmt.Println(Hello world)
}2) 自定义别名引用格式
在导入包的时候我们还可以为导入的包设置别名如下所示 import F fmt其中 F 就是 fmt 包的别名使用时我们可以使用F.来代替标准引用格式的fmt.来作为前缀使用 fmt 包中的方法。
示例代码如下 package main
import F fmt
func main() {F.Println(Hello world)
}3) 省略引用格式 import . fmt这种格式相当于把 fmt 包直接合并到当前程序中在使用 fmt 包内的方法是可以不用加前缀fmt.直接引用。
示例代码如下 package main
import . fmt
func main() { Println(Hello world)
}4) 匿名引用格式
在引用某个包时如果只是希望执行包初始化的 init 函数而不使用包内部的数据时可以使用匿名引用格式如下所示 import _ fmt匿名导入的包与其他方式导入的包一样都会被编译到可执行文件中。
使用标准格式引用包但是代码中却没有使用包编译器会报错。如果包中有 init 初始化函数则通过import _ “包的路径” 这种方式引用包仅执行包的初始化函数即使包没有 init 初始化函数也不会引发编译器报错。
示例代码如下 package main
import (_ github.com/astaxie/beegofmt
)
func main() {fmt.Println(Hello world)
}注意
一个包可以有多个 init 函数包加载时会执行全部的 init 函数但并不能保证执行顺序所以不建议在一个包中放入多个 init 函数将需要初始化的逻辑放到一个 init 函数里面。包不能出现环形引用的情况比如包 a 引用了包 b包 b 引用了包 c如果包 c 又引用了包 a则编译不能通过。包的重复引用是允许的比如包 a 引用了包 b 和包 c包 b 和包 c 都引用了包 d。这种场景相当于重复引用了 d这种情况是允许的并且 Go 编译器保证包 d 的 init 函数只会执行一次。 这块大家可以多练习练习尝试下凡是和语言相关的知识在初步学习过程中要不断地练习和尝试就会有不一样的角度的理解。
包的初始化顺序
在分享包的初始化顺序之前有必要了解下init函数和main函数
init函数
go语言中init函数用于包(package)的初始化该函数是go语言的一个重要特性。
有下面的特征 1 init函数是用于程序执行前做包的初始化的函数比如初始化包里的变量等2 每个包可以拥有多个init函数3 包的每个源文件也可以拥有多个init函数4 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)5 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序6 init函数不能被其他函数调用而是在main函数执行之前自动被调用
main函数 Go语言程序的默认入口函数(主函数)func main() 函数体用一对括号包裹。
func main(){//函数体}
init函数和main函数的异同 相同点两个函数在定义时不能有任何的参数和返回值且Go程序自动调用。不同点init可以应用于任意包中且可以重复定义多个。main函数只能用于main包中且只能定义一个。
两个函数的执行顺序
对同一个go文件的init()调用顺序是从上到下的。
对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()函数。
对于不同的package如果不相互依赖的话按照main包中”先import的后调用”的顺序调用其包中的init()如果package存在依赖则先调用最早被依赖的package中的init()最后调用main函数。
为了进一步看下init函数和main函数的初始化顺序我们可以看下这段代码 package mainimport (fmt
)
const (CFG_VISIT visit.json
)var (gameStatus 0
)func init(){fmt.Println(go init)
}func main(){fmt.Println(hello world)
} 对于import 包const 初始化 var初始化init函数main函数的调用顺序是什么样的
实际上整个程序的执行流程可以用下面的图来表示 总结下来go语言包的初始化有如下特点 包初始化程序从 main 函数引用的包开始逐级查找包的引用直到找到没有引用其他包的包最终生成一个包引用的有向无环图。golang编译器会将有向无环图转换为一棵树然后从树的叶子节点开始逐层向上对包进行初始化。单个包的初始化过程如上图所示先初始化常量然后是全局变量最后执行包的 init 函数。 内置类型
值类型 boolint(32 or 64), int8, int16, int32, int64uint(32 or 64), uint8(byte), uint16, uint32, uint64float32, float64stringcomplex64, complex128array -- 固定长度的数组 引用类型(指针类型) slice -- 序列数组(最常用)map -- 映射chan -- 管道 内置函数
Go 语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型进行操作例如len、cap 和 append或必须用于系统级的操作例如panic。因此它们需要直接获得编译器的支持。