跳到主要内容

2.Go基本语法

3.1 变量定义方法

var 定义变量

var name string = "zhangsan"
var age int = 21
var isOK bool

执行结果

package main

import "fmt"

func main() {
//变量定义: var 变量名 类型 = 值

var name string = "zhangsan"
var age int = 21
var isOk bool
var age2 int
fmt.Print(name,age,isOk,age2)

}

//-------------
zhangsan21 false 0

类型推导方式定义变量

a 在函数内部,可以使用更简略的 := 方式声明并初始化变量。

注意:短变量只能用于声明局部变量,不能用于全局变量的声明

// 变量名 := 表达式
n :=10
var age = 18

执行结果

package main

import "fmt"
func main() {
//类型推导方式定义 :=
n :=10
var age = 18
fmt.Print(name,age1,isOk,age2,n,age)
}

//zhangsan21 false 0 10 18

一次定义多个变量

package main

import "fmt"
func main() {
//变量定义: var 变量名 类型 = 值
var name string = "zhangsan"
var age1 int = 21
var isOk bool
var age2 int
//类型推导方式定义 :=
n :=10
var age = 18
fmt.Print(name,age1,isOk,age2,n,age)

//一次定义多个变量
var username , sex string
username = "张三"
sex = "男"
fmt.Println(username,sex)
}

执行结果

package main

import "fmt"
func main() {

//一次定义多个变量
var username , sex string
username = "张三"
sex = "男"
fmt.Println(username,sex)
}


//张三 男

批量声明变量

	var(
a string
b int
c bool
)
a = "张三"
b = 10
c = true
fmt.Println(a,b,c)

执行结果

package main

import "fmt"
func main() {
//批量声明变量
var(
a string
b int
c bool
)
a = "张三"
b = 10
c = true
fmt.Println(a,b,c)
}

//张三 10 true

3.2 常量定义

声明了 pi 和 e 这两个常量之后,在整个程序运行期间它们的值都不能再发生变化了。

//const pi = 3.1415
//const e = 2.7182

//多个常量可以一起声明

const (
pi = 3.1415
e = 2.1782
)

const 同时声明多个常量时,如果省略了值则表示和上面一行的值相同

const (
n1 = 100
n2
n3
)

3.3 fmt 包

  1. Println:
    • 可以一次输入多个值,并且值之间会自动加入空格。
    • 会自动换行。
  2. Print:
    • Println 类似,但是不会自动加空格和换行。
  3. Printf:
    • 支持格式化输出,可以更方便地控制输出格式。比如 %s 用来输出字符串,%d 用来输出整数。
  4. Sprintf:
    • Printf 相似,但是 Sprintf 返回的是格式化后的字符串,而不会直接输出。

在代码中使用这些函数时,要注意以下几点:

  • PrintPrintln 可以直接输出任意类型的变量。
  • Printf 需要指定格式字符串,每个变量需要对应的格式占位符。
  • Sprintf 只是生成一个格式化字符串,并不输出。
package main

import "fmt"

func main() {

fmt.Print("zhangsan", "lisi", "wangwu") // 不会有空格,不会换行
fmt.Println("zhangsan", "lisi", "wangwu") // 自动有空格并换行

name := "zhangsan"
age := 20
fmt.Printf("%s 今年 %d 岁", name, age) // 格式化输出

info := fmt.Sprintf("姓名: %s, 性别: %d", name, 20) // 格式化并返回字符串
fmt.Println(info) // 输出info字符串

}

//zhangsanlisiwangwuzhangsan lisi wangwu
//zhangsan 今年 20 岁姓名: zhangsan, 性别: 20

3.4 Init函数和函数和main函数函数

main 函数

// Go语言程序的默认入口函数(主函数):func main()
// 函数体用{}一对括号包裹

func main(){
//函数体
}

init 函数

go语言中 init 函数用于包 (package) 的初始化,该函数是go语言的一个重要特性。

有下面的特征:

  • init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
  • 每个包可以拥有多个init函数
  • 包的每个源文件也可以拥有多个init函数
  • 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
  • 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
  • init函数不能被其他函数调用,而是在main函数执行之前,自动被调用

init 函数和 main 函数的异同

相同点

  1. 无参数和返回值:
    • initmain 函数在定义时都不能有任何的参数和返回值。
  2. 自动调用:
    • Go 程序会自动调用 initmain 函数,无需手动调用。

不同点

  1. 使用场景:
    • init 函数可以存在于任意包中,用于执行包级别的初始化操作。
    • main 函数只能存在于 main 包中,是程序的入口函数。
  2. 定义数量:
    • 每个文件可以有多个 init 函数,并且每个 init 函数都会被调用。
    • main 函数在 main 包中只能定义一个。
  3. 调用顺序:
    • init 函数是按特定的顺序调用(稍后详述)。
    • main 函数是最后调用,用于启动程序。

init()函数介绍

3.5 golang 中关键字

  • var和const 变量和常量的声明
  • package and import 导入
  • func 用于定义函数和方法
  • return 用于从函数返回
  • defer 在函数退出之前执行
  • go 用于并行
  • select 用于选择不同类型的通讯
  • interface 用于定义接口
  • struct 用于定义抽象数据类型
  • break、case、continue、for、fallthrough、else、if、switch、goto、default 流程控制
  • chan 用于channel通讯
  • type 用于声明自定义类型
  • map 用于声明map类型数据
  • range 用于读取slice、map、channel数据

3.6 命名规范

Go是一门区分大小写的语言。命名规则涉及变量、常量、全局函数、结构、接口、方法等的命名。 Go语言从语法层面进行了以下限定:任何需要对外暴露的名字必须以大写字母开头,不需要对外暴露的则应该以小写字母开头。当命名(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Analysize,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的public);命名如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的private)

1. 包名称

保持与目录名称一致: 包名称应与其所在目录名称保持一致,确保项目结构清晰。

有意义且简短:包名应能够准确描述包的功能,并保持简短易读。避免过长或晦涩难懂的名称。

小写单词:包名应该全部为小写,避免使用大写字母、下划线或其他非字母字符。

避免冲突:尽量避免使用与标准库同名的包名,以免在导入时造成冲突。

示例:

package config  // 在路径 src/project/config 中,包名应为 config

2. 文件命名

小写单词和下划线:文件名应为小写单词,用下划线分隔多个单词。避免使用混合大小写或特殊字符。

有意义且简短:文件名应简洁明了,能够反映文件的主要内容或功能。

示例:

user_service.go   // 表示用户相关的服务
main_config.go // 主配置文件

3. 结构体命名

驼峰命名法(CamelCase):

结构体名称使用驼峰命名法,首字母根据访问控制规则决定大写或小写。

导出(可外部访问)的结构体以大写字母开头,包内私有的结构体以小写字母开头。

多行格式声明:结构体的字段应当使用多行格式声明,保持清晰的可读性。

示例:

type MainConfig struct {
Port string `json:"port"`
Address string `json:"address"`
}

4. 接口命名

er 结尾:

单个方法的接口命名通常以 er 作为后缀,比如 ReaderWriter。对于多个方法的接口,可以使用功能性名称,如 HandlerManager

方法声明:接口的方法命名遵循驼峰法,并使用有意义的参数和返回类型命名。

示例:

type Reader interface {
Read(p []byte) (n int, err error)
}

type Writer interface {
Write(p []byte) (n int, err error)
}

5. 变量命名

驼峰命名法:

变量命名遵循驼峰命名法,首字母根据访问控制规则决定大写或小写。包内私有变量以小写字母开头,导出变量以大写字母开头。

特有名词的处理:

当变量名包含特有名词时,如 HTTPURL,如果它们出现在变量名开头并且是私有变量,应使用小写,如 httpRequest

布尔类型变量命名:

对于布尔类型的变量,通常使用 HasIsCanAllow 作为前缀,以反映其含义。

示例:

var isExist bool         // 表示是否存在
var hasConflict bool // 表示是否有冲突
var canManage bool // 表示是否能够管理
var allowGitHook bool // 表示是否允许 Git 钩子

6. 常量命名

  1. 全大写字母和下划线:
    • 常量使用全大写字母,并用下划线分隔单词。
  2. 枚举类型常量:
    • 对于枚举类型的常量,应先声明自定义类型,再定义一组相关的常量。

示例:

const APP_URL = "https://www.baidu.com"

type Scheme string

const (
HTTP Scheme = "http"
HTTPS Scheme = "https"
)

7. 其他命名规则

  1. 函数命名:
  • 函数名称同样遵循驼峰命名法。导出函数(public)以大写字母开头,私有函数(private)以小写字母开头。
  1. 方法命名:
  • 接收者方法的命名应尽量简洁明了,反映方法的主要功能。首字母大小写决定了方法的导出属性。
  1. 缩写词处理:
  • 如果命名中包含缩写词,缩写词应保持一致的大小写风格。例如,HTTPServerhttpServer