Go 基础入门
创始人
2025-05-30 14:59:29
0

1. 变量

Go 语言是静态类型语言,由于编译时,编译器会检查变量的类型,所以要求所有的变量都要有明确的类型

变量在使用前,需要先声明。声明类型,就约定了你这个变量只能赋该类型的值。

1.1 变量声明

格式:var 变量名 类型 = 值

声明方式大概有四种,若声明时没有初始化,那么其默认值为该数据类型的 0 值,比如: string 类型就初始化为空字符串,int 类型就初始化为0,float 就初始化为 0.0,bool 类型就初始化为 false,指针类型就初始化为 nil

1、一行声明一个变量,并初始化值

var name string = "变量"

2、一次声明多个变量

var (age intgender string)

3、声明和初始化一个变量

使用 :=(让编译器自动根据右侧的值推测出左侧的变量数据类型),这种方法只能用于函数内部

name := "Go 变量"// 等同
var name string = "Go 变量"

4、声明和初始化多个变量

name, age := "rose", 18// 可以用来做变量交换
var a int = 100
var b int = 200
b, a = a, b

1.2 全局变量和局部变量

根据变量位置可将变量划分为全局变量和全局变量,Go 变量有作用域之分,每个大括号就是一个作用域,每个作用域都可以有相应的局部变量。

全局变量

全局可使用

package mainimport "fmt"// 声明全局变量
var country = "中国"func main() {fmt.Println(country)country = "China"fmt.Println(country)
}

输出:

中国
China

注意:全局变量首字母小写,只能用于当前包中,大写可用于其他包文件,即外部可使用

局部变量

仅对应作用域可使用

package mainimport "fmt"func main() {// 声明局部变量,在当前函数中使用var country = "China"fmt.Println(country)if true {// 声明局部变量,仅在 if 中使用var age = 18fmt.Println(age)fmt.Println(country)}// age 不能在 if 作用域外使用// fmt.Println(age)}

输出:

China
18
China

country 可在当前函数作用域中使用,但 age 不能在 if 作用域外使用。

1.3 指针变量

变量分为两种:

  • 普通变量:存储的为数据本身
  • 指针变量:存储的为数据/内存地址

指针变量声明可以使用 new 函数,也可以使用 &普通变量

package mainimport "fmt"func main() {// 指针变量,方法一var name string = "rose"var ptr = &name		// & 后面接变量名,表示取出该变量的内存地址fmt.Println(name)	// rosefmt.Println(ptr)	// 0xc00005e270// 指针变量,方法二 new 函数ptr2 := new(int)fmt.Println(ptr2)	// 0xc0000a6090fmt.Println(*ptr2)	// * 指针变量名,表示从内存中取出值、0
}

使用表达式 new(Type) 将创建一个Type类型的匿名变量,初始化为Type类型的零值,然后返回变量地址,返回的指针类型为*Type

1.4 匿名变量

常量和变量都只能声明一次,声明多次就会编译报错,匿名变量除外,它有如下优点:

  • 不分配内存,不占用内存空间
  • 不需要你为命名无用的变量名而纠结
  • 多次声明不会有任何问题

一般可以用来接收必须接收,但又用不到的值:

func GetData() (int, int) {return 100, 200
}
func main(){a, _ := GetData()_, b := GetData()fmt.Println(a, b)
}

2. 常量

常量即不可被修改的变量,支持的类型:数字型(整型、浮点型和复数)、字符串型、布尔型,如:

// 声明变量
var name = "rose"// 声明常量
var age = 18
const age1 = 18

2.1 因式分解

const (v1 = 123  v2 = 456v3 = 789v4 = 101112
)

2.2 iota

特殊变量,可以认为是一个可修改的常量,在 const 关键字出现时被重置为 0 (const 内部的第一行之前),const 每新增一行,常量声明将使 iota 计数一次,可理解为 const 语句块中的行索引。

const (v1 = iotav2 = iotav3 = iota
)

v1 = 0v2、v3 分别为 1、2,可简写如下:

const (v1 = iotav2v3
)

示例一

package mainimport "fmt"func main() {const (v1 = iota + 2v2v3)fmt.Println(v1, v2, v3)const (v4 = iota + 2_v5v6)fmt.Println(v4, v5, v6)
}

输出:

2 3 4
2 4 5

示例二

package mainimport "fmt"func main() {const (i=1<
  • <<:表示左移
  • iota 初始为 0,i 左移 0 位,值不变仍为 1
  • j 左移 1 位,变为二进制 110,即 6
  • k 左移 2 为,变为二进制:1100,即 12
  • l 左移 3 为,变为二进制:11000,即 24

注意:<

3. 输入

接收输入的有三个函数,分别为:

  • fmt.Scan:从标准输入扫描用户输入的数据,将以空白符分隔的数据分别存入指定的函数
  • fmt.Scanln:遇到换行时才停止扫描,最后一个数据后面必须有换行或者到达结束位置
  • fmt.Scanf:按指定格式扫描输入的数据

3.1 Scan

从标准输入扫描文本,读取由空白符分隔的值保存到传递给本函数的参数中,换行符视为空白符。

本函数返回成功扫描的数据格式和遇到的任务错误,若读取的数据个数比提供的参数少,会返回一个错误报告原因。

1、接收一个参数:

package mainimport "fmt"func main() {var name stringfmt.Println("请输入用户名:")fmt.Scan(&name)fmt.Printf(name)
}

输出:

[root@localhost test]# go run test.go 
请输入用户名:
rose
rose

2、接收两个参数:

package mainimport "fmt"func main() {var name stringvar age intfmt.Println("请输入用户名:")_, err := fmt.Scan(&name, &age)if err == nil {fmt.Println(name, age)} else {fmt.Println("用户输入数据错误", err)}
}

运行结果:

请输入用户名:
rose 18
rose 18

3.2 Scanln

类似 Scan,遇到换行时才停止扫描,最后一个数据后面必须有换行或者到达结束位置。

返回成功扫描的数据个数和遇到的任何错误。

package mainimport "fmt"func main() {var (name stringage intgender string)fmt.Println("请输入参数:")fmt.Scanln(&name, &age, &gender)fmt.Println(name, age, gender)
}

运行结果:

// 空格不会停止扫描
请输入参数:
rose 19 female
rose 19 female// 回车会停止扫描
请输入参数:
rose
rose 0 

3.3 Scanf

从标准输入扫描文本,根据 format 参数指定的格式去读取由空白符分隔的值保存到传递给本函数的参数中。

返回成功扫描的数据个数和遇到的任何错误。

package mainimport "fmt"func main() {var (name stringage int)fmt.Println("请输入参数:")_, _ = fmt.Scanf("我叫:%s 今年:%d 岁", &name, &age)fmt.Println(name, age)
}

fmt.Scanf 不能以简单的空格符作为输入数据的分隔符,它指定了具体的输入格式,只有按照格式输入数据才会被扫描并存入对应变量,否则不能正确扫描到输入的数据。

3.4 读取一整行

fmt.Scan 以空白符区分输入的参数,若输入的是一整行,且单次之间相互有空格,那么使用 fmt.Scan 就会报错,若想读取一整行可以使用:

package mainimport ("bufio""fmt""os"
)func main() {reader := bufio.NewReader(os.Stdin)// line 从 stdin 中读取一行的数据,字节集合,转换为字符串line, _, _ := reader.ReadLine()data := string(line)fmt.Println(data)
}

运行结果:

// 输入的数据
格式化输入输出的用法请参考 aaaa fff gghh arr// 打印的数据
格式化输入输出的用法请参考 aaaa fff gghh arr

reader 默认一次能读取 4096 个字节,一次性读完:isPrefix=false,先读一部分:isPrefix=true,再去读取:isPrefix=false

相关内容

热门资讯

河南鹤壁一水库水位下降惊现千佛... 极目新闻记者 王鹏 近日,有网友发视频称,河南省鹤壁市淇县夺丰水库水位下降,露出一处石洞。石洞洞口虽...
热点追踪|国际调解院要来了 5月30日,国际调解院公约签署仪式在香港举行。来自亚洲、非洲、拉美和欧洲85个国家和近20个国际组织...
陈妤颉获田径亚锦赛女子200米... 北京时间5月31日,2025亚洲田径锦标赛继续进行。 女子200米决赛,16岁小将陈妤颉以22秒97...
法治面|“机器人律师”离我们还... 界面新闻记者 | 蔡星卓 界面新闻编辑 | 刘海川 2025年3月,一个出现在美国纽约法庭上的虚...
加州州长批联邦政府关税政策“非... 每经AI快讯,美国加利福尼亚州州长纽森在当地时间5月30日播出的一档节目中,批评联邦政府“单边”且“...
volatile和Java内存... 文章目录1、volatile2、volatile的内存语义3、内存屏障3.1、是什么、能干嘛3.2、...
“法治+非遗”剧本杀来了!设计... 5月30日,广州市人民检察院联合广州市文化广电旅游局举办“携手关爱,共护未来”暨“文化赋能保护,法治...
终于等到你!Guitar Pr... Guitar Pro是一款非常流行的音乐制谱软件它不仅适用于吉他谱还可以用于其他乐器的制谱。历经5年...
Java中的直接赋值、浅拷贝和... 将一个对象的引用复制给另外一个对象,一共有三种方式。第一种方式是直接赋值,...