草庐IT

02 Golang 基础简介

cdcx 2023-03-28 原文

一、标识符

标识符是指定义的具有特殊意义的词,例如变量、常量、函数名等等,任何一门语言中都对自己的标识符有特殊定义的规则。在 Go 语言中,标识符由字母数字和下划线组成,并且只能以字母和下划线开头,例如:

  • 数字、字母和下划线组成:123abc _

  • 只能以字母和下划线开头:abc123_sysVar123abc

  • 标识符区分大小写:nameNameNAME

二、关键字和保留字

关键字和保留字是指编程语言中预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名,会引起混乱和冲突。

1. GO中的关键字

    break        default      func         interface    select
    case         defer        go           map          struct
    chan         else         goto         package      switch
    const        fallthrough  if           range        type
    continue     for          import       return       var

2. GO中的保留字

 Constants:    true  false  iota  nil
​
     Types:    int  int8  int16  int32  int64  
               uint  uint8  uint16  uint32  uint64  uintptr
               float32  float64  complex128  complex64
               bool  byte  rune  string  error
​
  Functions:   make  len  cap  new  append  copy  close  delete
               complex  real  imag
               panic  recover

三、命名规范

由于Go语言是一门区分大小写的语言,因此Go从语法层面进行了以下限定:任何需要对外暴露的名字必须以大写字母开头,不需要对外暴露的则应该以小写字母开头。

当命名(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:GetUserName,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(程序需要先导入这个包),这被称为导出(类似面向对象语言中的公共属性); 命名如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(类似面向对象语言中的私有属性 )。

Go语言中各类情形的建议命名规则如下:

  • 变量命名

变量名称一般遵循驼峰法,首字母根据访问控制原则大写或者小写

1 var userName string
2 var isExist bool
  • 常量命名

常量均需使用全部大写字母组成,并使用下划线分词

const SITE_URL = "http://www.chendacheng.com"
  • 结构体命名

采用驼峰命名法,首字母根据访问控制大写或者小写

1 type UserInfo struct {
2     Name string,
3     age  int,
4 }
  • 接口命名

命名规则基本和上面的结构体类型,单个函数的结构名以er作为后缀

1 type Reader interface {
2      Read(p []byte) (n int, err error)
3 }
  • 错误处理

错误处理的原则就是不能丢弃任何有返回err的调用,不要使用_丢弃,必须全部处理。接收到错误,要么返回err,或者使用log记录下来尽早return。一旦有错误发生,马上返回,尽量不要使用panic,除非你知道你在做什么,错误描述如果是英文必须为小写,不需要标点结尾,采用独立的错误流进行处理。

1 if err != nil {
2     // 错误处理
3     return // 或者继续
4 }
5 // 正常代码
  • 包命名

尽量保持和目录保持一致,采取有意义的包名,简短且不要和标准库不要冲突。包名应该为小写单词,不要使用下划线或者混合大小写。

1 package dao
2 package service
3 package main
  • 文件命名

尽量采取简短且有意义的文件名,应该为小写单词,使用下划线分隔各个单词。

1 customer_dao.go
2 user_manage.go
  • 单元测试

单元测试文件名要以 _test.go结尾,测试文件中的测试用例的函数名称必须以 Test 开头。

四、变量

变量的作用是存储数据,不同的变量保存的数据类型可能会不一样。Go 语言中的每一个变量都有自己的类型,变量必须经过声明才能开始使用,且同一作用域内不支持重复声明

1. 变量的作用域

1.1 全局变量和局部变量

变量可以定义在函数内部(函数外的每个语句都必须以关键字开始,如:varconstfunc等),也可以定义在函数内部。定义在函数外部的变量称为 全局变量,定义在函数内部的变量称为 局部变量 。在 GO 语言中,定义的局部变量必须使用,否则编译代码的时候将不被通过,定义的全局变量可以不使用。

1 package main
2 3 var name string = "cdc" // 定义一个全局变量
4 5 func main() {
6 7 }

直接编译通过:

1 package main
2 3 func main() {
4     name := "cdc"  // 声明并初始化了一个局部变量,但是未使用
5 }

直接编译未通过,报错:

1.2 作用域

  • 函数内可以使用全局的变量,但是在全局无法使用局部的变量

 1 var name = "cdc"
 2  3 func main() {
 4     fmt.Printf("%v\n", name)  // cdc
 5 }
 6 func demo() {
 7     var name = "cdc"
 8 }
 9 10 func main() {
11     fmt.Printf("%v\n", name) // undefined: namet
12 13 }
  • 代码执行时,先从函数内部寻找局部变量,找不到再去找全局的变量

 1 package main
 2  3 import "fmt"
 4  5 var name = "cdc"
 6 var age = 22
 7  8 func main() {
 9 10     var name = "ctt"
11     
12 13     fmt.Printf("%v\n", name) // ctt
14     fmt.Printf("%v\n", age)  // 22
15 }

2. 变量的声明

2.1 标准声明方式

变量声明以关键字 var 开头,变量类型放在变量的后面,行尾无需分号。

1 var name string
2 var age int
3 var isOk bool

2.2 批量声明

1 var (
2     a string
3     b int
4     c bool
5     d float32
6 )

注意:在没有初始化变量之前,不同数据类型的变量会有一个默认值,值为该数据类型对应的0值:

 1 package main
 2  3 import "fmt"
 4  5 func main() {
 6     var (
 7         a string
 8         b int
 9         c bool
10         d float32
11     )
12 13     fmt.Println(a) // ""
14     fmt.Println(b) // 0
15     fmt.Println(c) // false
16     fmt.Println(d) // 0
17 }

3. 变量初始化

3.1 标准初始化格式

1 var name string = "cdc"
2 var age int = 18
3 4 // 一次声明多个变量
5 var age, isOk = 18, true

3.2 类型推导

有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化

 1 package main
 2  3 import "fmt"
 4  5 func main() {
 6     var name = "cdc" // 编译器会根据 “cdc” 推导出变量 name 是一个字符串类型
 7     var age = 18
 8  9     fmt.Printf("%T\n", name) // string
10     fmt.Printf("%T\n", age)  // int
11 }

3.3 短变量声明

短变量声明方式只能用于函数内部

 1 package main
 2  3 import "fmt"
 4  5 // 全局变量m
 6 var m = 100
 7  8 func main() {
 9     n := 10
10     m := 200 // 此处声明局部变量m
11     fmt.Println(m, n)
12 }

3.4 匿名变量

对于声明的局部变量必须要使用,否则编译无法通过。如果想要忽略某个值,我们可以使用 匿名变量 来接收该值 。匿名变量用一个下划线表示,它不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明,例如:

 1 package main
 2  3 import "fmt"
 4  5 func function1() (string, int) {
 6     return "cdc", 18
 7 }
 8  9 func main() {
10     var name, _ = function1()
11     fmt.Printf("My name is %s", name)
12 }

匿名变量 _ 并未使用,但是编译可以通过

五、常量

常量是指恒定不变的值,多用于定义程序运行期间不会改变的那些值,一旦定义了常量后就无法修改。

1. 标准声明格式

1 const PI = 3.1415
2 const E = 2.7182

2. 批量声明

1 const (
2     STATUS_OK = 200
3     NOT_FOUND = 404
4 )

批量声明常量时,如果某一行声明之后没有赋值,那么后面的常量就默认和上一行一致

 1 package main
 2  3 import "fmt"
 4  5 const (
 6     n1 = 100
 7     n2 = 200
 8     n3
 9     n4
10 )
11 12 func main() {
13     fmt.Printf("n1:%v\n", n1)
14     fmt.Printf("n2:%v\n", n2)
15     fmt.Printf("n3:%v\n", n3)
16     fmt.Printf("n4:%v\n", n4)
17 }

编译执行结果如下,n3n4 的值都为 200:

3. iota

iota 是go语言的常量计数器,只能在常量的表达式中使用。iotaconst 关键字出现时将被重置为0,const 中每新增一行常量声明将使 iota 计数一次。可以直接理解 iota 其实就是每一行代码的索引值。

  • 示例1:

 1 package main
 2  3 import "fmt"
 4  5 const (
 6     a1 = iota
 7     a2 = iota
 8     a3 = iota
 9     a4 = iota
10 )
11 12 func main() {
13     fmt.Printf("a1:%d\n", a1)
14     fmt.Printf("a2:%d\n", a2)
15     fmt.Printf("a3:%d\n", a3)
16     fmt.Printf("a4:%d\n", a4)
17 }

分析:出现了 const 关键字,所以 a1 对应的 iota 的值为 0;后面每新增一行常量的声明,iota 的值就累加1,所以最后打印的结果为:

  • 示例2,省略 iota

 1 package main
 2  3 import "fmt"
 4  5 const (
 6     b1 = iota
 7     b2
 8     b3
 9     b4
10 )
11 12 func main() {
13     fmt.Printf("b1:%d\n", b1)
14     fmt.Printf("b2:%d\n", b2)
15     fmt.Printf("b3:%d\n", b3)
16     fmt.Printf("b4:%d\n", b4)
17 }

分析:出现了 const 关键字,所以 b1 对应的 iota 的值为 0;由于常量批量声明的规则,当某一行声明之后没有赋值,那么后面的常量就默认和上一行一致,所以理论上 b2 的值应该也为 iota,每新增一行常量的声明,iota 的值就累加1,所以 b2 的值应该为1,以此类推,最后打印的结果为:

  • 示例3,使用 _ 跳过某些值:

 1 package main
 2  3 import "fmt"
 4  5 func main() {
 6     const (
 7         n1 = iota
 8         n2
 9         _
10         n4
11     )
12 13     fmt.Printf("n1: %d\n", n1)
14     fmt.Printf("n2: %d\n", n2)
15     fmt.Printf("n4: %d\n", n4)
16 }

分析:出现了 const 关键字,所以 n1 对应的 iota 的值为 0;由于常量批量声明的规则,当某一行声明之后没有赋值,那么后面的常量就默认和上一行一致,所以理论上 n2 的值应该也为 iota,每新增一行常量的声明,iota 的值就累加1,所以 n2 的值应该为1;虽然匿名变量会被跳过,但是也是作为一个常量声明的,也会遵循只要新增一行常量声明 iota 就累加1的规则,所以匿名变量对应的值应该是2,以此类推,最后编译打印的结果为:

  • 示例4,iota 声明中间插队:

 1 package main
 2  3 import "fmt"
 4  5 func main() {
 6     const (
 7         n1 = iota
 8         n2 = 100
 9         n3 = iota
10         n4
11     )
12 13     fmt.Printf("n1: %d\n", n1)
14     fmt.Printf("n3: %d\n", n2)
15     fmt.Printf("n4: %d\n", n4)
16 }

分析:出现了 const 关键字,所以 n1 对应的 iota 的值为 0;虽然 n2 没有使用到 iota,但是 iota 是对当前批量声明的常量做统计的,只要新增了一行常量声明,值就累加 1 ,因此声明 n2 时,iota 还是会加 1,以此类推,最后编译打印的结果为:

  • 示例5,多个iota定义在一行

 1 package main
 2  3 import "fmt"
 4  5 func main() {
 6     const (
 7         n1, n2 = iota + 1, iota + 2
 8         n3, n4 = iota + 1, iota + 2
 9     )
10 11     fmt.Printf("n1: %d\n", n1)
12     fmt.Printf("n2: %d\n", n2)
13     fmt.Printf("n3: %d\n", n3)
14     fmt.Printf("n4: %d\n", n4)
15 }

分析:只要每新增了一行常量声明,iota 值就累加 1 ,但是 n1n2 是在一行声明的,所以对于 n1n2iota 的值都为 0;到声明 n3n4 的时候才是新增了一行声明,这时的 iota 的值才会累加 1,编译运行的结果如下:

  • 示例6,使用 iota 定义数量级

1 const (
2         _  = iota
3         KB = 1 << (10 * iota)
4         MB = 1 << (10 * iota)
5         GB = 1 << (10 * iota)
6         TB = 1 << (10 * iota)
7         PB = 1 << (10 * iota)
8 )

有关02 Golang 基础简介的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  3. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  4. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  5. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  6. 牛客网专项练习30天Pytnon篇第02天 - 2

    1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析:    在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1:    print(k)k=k/2A.1000 B.10C.11D.9解析:    按照题意每次循环K/2,直到K值小于等

  7. 【网络】-- 网络基础 - 2

    (本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展        是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。    如:有三个人,每个人做的不同的事物,但是是需要协作的完成。    而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据

  8. IDEA 2023.1 正式发布,新特性简介 - 2

     昨晚看到IDEA官推宣布IntelliJIDEA2023.1正式发布了。简单看了一下,发现这次的新版本包含了许多改进,进一步优化了用户体验,提高了便捷性。至于是否升级最新版本完全是个人意愿,如果觉得新版本没有让自己感兴趣的改进,完全就不用升级,影响不大。软件的版本迭代非常正常,正确看待即可,不持续改进就会慢慢被淘汰!根据官方介绍:IntelliJIDEA2023.1针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施,使得Maven导入更快,并且在打开项目时IDE功能更早地可用。由于后台提交检查,新版本提供了简化的提交流程。IntelliJIDEA

  9. 【Elasticsearch基础】Elasticsearch索引、文档以及映射操作详解 - 2

    文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就

  10. c++基础-运算符 - 2

    目录1关系运算符2运算符优先级3关系表达式的书写代码实例:下面是面试中可能遇到的问题:1关系运算符C++中有6个关系运算符,用于比较两个值的大小关系,它们分别是:运算符描述==等于!=不等于小于>大于小于等于>=大于等于这些运算符返回一个布尔值,即true或false。例如,当x等于y时,x==y的结果为true,否则结果为false。2运算符优先级在C++中,关系运算符的优先级高于赋值运算符,但低于算术运算符。以下是关系运算符的优先级,从高到低排列:运算符描述>,,>=,关系运算符==,!=相等性运算符&&逻辑与`如果在表达式中有多个运算符,则按照优先级顺序依次进行运算。3关系表达式的书写在

随机推荐