Go语法入门:变量、函数与基础数据类型
🚀 Go语法入门:变量、函数与基础数据类型(零基础也能懂)
大家好!上一篇我们搭建好了Go的开发环境,今天终于要正式踏入Go的世界啦~
这篇文章会带你吃透Go的「基本功」:变量怎么定义?有哪些常用数据类型?函数怎么写?全程代码示例+通俗解释,保证零基础小白也能看懂。学会这些,你就能写出有实际功能的Go代码了,go go go 出发喽!
一、变量:程序的“储物盒”
变量就像一个个被贴了标签的盒子,用来存放数据(数字、文字、布尔值等)。比如你可以用一个叫age
的变量存年龄,用name
存名字。
1. 变量的声明与初始化
Go语言声明变量有几种方式,新手先掌握这3种最常用的:
▶ 方式1:完整声明(var
关键字)
格式:var 变量名 数据类型 = 初始值
package mainimport "fmt"func main() {// 声明并初始化一个字符串变量var name string = "熊初墨"// 声明并初始化一个整数变量var age int = 18// 打印变量(%s对应字符串,%d对应整数)fmt.Printf("我叫%s,刚满%d岁~~~", name, age)
}
运行结果:我叫熊初墨,刚满18岁~~~
▶ 方式2:类型推断(省略数据类型)
如果初始化时给了值,Go能自动判断类型,可以简写:
var height = 1.75 // 自动推断为float64(小数类型)
var isStudent = true // 自动推断为bool(布尔类型)
▶ 方式3:短变量声明(最常用!)
在函数内部可以用:=
快速声明变量(必须初始化,且只能在函数里用):
func main() {score := 95 // 等价于 var score int = 95subject := "数学"fmt.Printf("%s成绩:%d分\n", subject, score) // 输出:数学成绩:95分
}
2. 变量使用注意事项
- 声明后必须使用:Go不允许定义变量后不用(会报错),避免浪费资源;
- 强类型语言:变量类型一旦确定,不能随便赋值其他类型(比如
age int = "25"
会报错); - 批量声明:可以一次性声明多个变量,更简洁:
// 批量声明(适合多个同类型或不同类型变量) var (a int = 10b string = "hello"c bool = false )// 批量短声明 x, y := 3.14, "π的值"
二、基础数据类型:Go中的“积木块”
Go是强类型语言,每个变量都有明确的类型。掌握以下常用类型,能应对80%的场景:
1. 整数类型(存整数)
类型 | 范围(举例) | 说明 |
---|---|---|
int | 32位系统占4字节,64位占8字节 | 日常用得最多,自动适配系统 |
int8 | -128 到 127 | 占1字节,节省空间时用 |
int16 | -32768 到 32767 | 占2字节 |
int32 | -2^31 到 2^31-1 | 常用在网络传输、时间戳 |
int64 | -2^63 到 2^63-1 | 存大整数(比如人口数) |
uint | 0 到 2^32-1 或 2^64-1 | 无符号整数(只存正数) |
示例:
func main() {var num1 int = 100 // 默认整数类型var num2 int8 = 127 // 最大int8值var num3 uint = 200 // 无符号整数(不能为负)fmt.Println(num1, num2, num3) // 输出:100 127 200
}
2. 浮点类型(存小数)
类型 | 精度 | 说明 |
---|---|---|
float32 | 约6-7位小数 | 精度较低,占4字节 |
float64 | 约15-17位小数 | 精度高,占8字节,默认浮点类型 |
示例:
func main() {pi := 3.1415926 // 默认是float64var height float32 = 1.75 // 显式声明float32fmt.Println(pi, height) // 输出:3.1415926 1.75
}
3. 布尔类型(存真假)
只有两个值:true
(真)和false
(假),常用于条件判断。
示例:
func main() {isGoFun := truehasError := falsefmt.Println("Go有趣吗?", isGoFun) // 输出:Go有趣吗? true
}
4. 字符串类型(存文字)
用string
表示,用双引号 ""
或反引号 `` 包裹,是日常开发中最常用的类型之一。
示例:
func main() {// 双引号:支持转义字符(\n换行、\t制表符等)msg1 := "Hello\nGo"// 反引号:原样输出(适合多行文本、路径)msg2 := `C:\Program Files\Go
这是第二行`fmt.Println(msg1)fmt.Println("---")fmt.Println(msg2)
}
输出结果:
Hello
Go
---
C:\Program Files\Go
这是第二行
字符串常用操作:
func main() {s1 := "Hello"s2 := "Go"// 字符串拼接(用+号)s3 := s1 + " " + s2 // 结果:"Hello Go"// 求长度(按字节数,英文1字节,中文通常3字节)len1 := len(s3) // 结果:8(H e l l o 空格 G o → 8个字符)fmt.Println(s3, len1)//控制台结果:Hello Go 8
}
5. 字符类型(存单个字符)
Go中用rune
(等价于int32
)表示单个Unicode字符(包括中文、英文、符号等),用单引号''
包裹。
示例:
func main() {c1 := 'A' // 英文字符c2 := '中' // 中文字符c3 := '☆' // 特殊符号( Unicode 字符)fmt.Printf("字符:%c,对应的ASCII值:%d\n", c1, c1) //字符:A,对应的ASCII值:65fmt.Printf("字符:%c,对应的Unicode值:%d\n", c2, c2) //字符:中,对应的Unicode值:20013fmt.Printf("字符:%c,对应的Unicode值:%d\n", c3, c3) //字符:☆,对应的Unicode值:9734
}
三、函数:代码的“功能模块”
函数就像一个“工具”,把一段实现特定功能的代码封装起来,需要时直接调用,避免重复编写。比如计算加法、打印日志等,都可以写成函数。
1. 函数的定义格式
func 函数名(参数列表) 返回值类型 {// 函数体(实现功能的代码)return 返回值 // 如果有返回值,必须用return返回
}
2. 函数的4种常见形式
▶ ① 无参数、无返回值
// 定义函数:打印欢迎信息
func printWelcome() {fmt.Println("欢迎学习Go语言!")
}// 调用函数(在main函数中)
func main() {printWelcome() // 输出:欢迎学习Go语言!
}
▶ ② 有参数、无返回值
// 定义函数
func printInfo(value string, item string) {fmt.Printf("一给%s,giao%s!", value, item)
}// 调用时传入参数(顺序和类型必须匹配)
func main() {printInfo("我里", "giao")//终端值:一给我里,giaogiao!
}
▶ ③ 有参数、有返回值
// 定义函数:计算两个数的和(返回值类型是int)
func add(a int, b int) int {sum := a + breturn sum // 返回计算结果
}func main() {// 调用函数,用变量接收返回值result := add(3, 5)fmt.Println("3+5=", result) // 输出:3+5= 8
}
▶ ④ 多返回值(Go的特色!)
Go支持一个函数返回多个值,非常适合返回“结果+错误信息”这类场景。
// 定义函数:除法(返回商和错误信息)
func divide(a, b float64) (float64, string) {if b == 0 {return 0, "错误:除数不能为0" // 返回0和错误信息}return a / b, "" // 返回商和空字符串(表示无错误)
}func main() {// 接收两个返回值res, err := divide(10, 2)if err == "" {fmt.Println("结果:", res) // 输出:结果:5} else {fmt.Println(err)}res2, err2 := divide(5, 0)fmt.Println(res2, err2) // 输出:0 错误:除数不能为0
}
3. 函数命名规则
- 字母开头,可包含数字和下划线
_
; - 区分大小写(
add
和Add
是两个不同函数); - 建议用动词或动词短语(比如
printInfo
、calculateSum
),见名知意。
此处插入一条重要的知识点:
如果在以上的每一个知识点中大家都自己亲手敲过一遍小案例的话相信大家也发现了,在终端打印结果的时候,有时候用的是Println
有时候用的是Printf
那这两个有啥区别呢?下面我来给大家补充一下这部分的知识点。
在Go语言中,Println
和 Printf
都是用于格式化输出的函数,但它们有一些重要区别:
Println
- 功能:用于打印一系列值,并在最后自动添加换行符。每个值之间会添加一个空格分隔。它主要用于简单、快速地输出信息,不需要对输出格式进行精细控制的场景。
- 示例:
package mainimport "fmt"func main() {num := 10str := "Hello"fmt.Println(num, str)
}
- 输出:
10 Hello
Printf
- 功能:用于格式化输出,它允许通过格式化字符串来控制输出的格式。格式化字符串中可以包含占位符,用于指定后续参数的输出格式。例如,
%d
用于输出整数,%s
用于输出字符串,%.2f
用于保留两位小数输出浮点数等。这种方式在需要对输出进行精确格式控制时非常有用。 - 示例:
package mainimport "fmt"func main() {num := 10str := "Hello"fmt.Printf("数字: %d, 字符串: %s\n", num, str)
}
- 输出:
数字: 10, 字符串: Hello
其他常用函数
Sprintf
- 功能:它与
Printf
类似,但它不会将格式化后的字符串输出到标准输出,而是返回一个格式化后的字符串。这在需要将格式化后的内容作为字符串使用,而不是直接打印时非常有用,比如将格式化后的字符串赋值给一个变量,或者用于日志记录等。 - 示例:
package mainimport "fmt"func main() {num := 10str := "Hello"result := fmt.Sprintf("数字: %d, 字符串: %s", num, str)fmt.Println(result)
}
- 输出:
数字: 10, 字符串: Hello
Fprintf
- 功能:用于将格式化后的内容写入到一个实现了
io.Writer
接口的对象中,而不是标准输出。这在需要将输出写入到文件、网络连接等场景中非常有用。例如,要将日志写入文件,可以使用Fprintf
。 - 示例:
package mainimport ("fmt""os"
)func main() {file, err := os.Create("output.txt")if err != nil {fmt.Println("创建文件失败:", err)return}defer file.Close()num := 10str := "Hello"fmt.Fprintf(file, "数字: %d, 字符串: %s", num, str)
}
在上述示例中,fmt.Fprintf
将格式化后的内容写入到名为 output.txt
的文件中。
除此以外,还有一些较为常用的函数我就不一一进行列举了,提供以下表格供大家可以进查看和学习。
函数名 | 功能描述 | 示例 | 输出示例 |
---|---|---|---|
fmt.Print | 将一系列值输出到标准输出,值之间无分隔符,不自动换行 | fmt.Print("Hello", "World") | HelloWorld |
fmt.Println | 将一系列值输出到标准输出,值之间用空格分隔,最后自动换行 | fmt.Println("Hello", "World") | Hello World (换行) |
fmt.Printf | 按照格式化字符串指定的格式将值输出到标准输出 | fmt.Printf("数字: %d, 字符串: %s", 10, "Hello") | 数字: 10, 字符串: Hello |
fmt.Sprintf | 按照格式化字符串指定的格式返回一个格式化后的字符串,不进行输出 | result := fmt.Sprintf("数字: %d, 字符串: %s", 10, "Hello") fmt.Println(result) | 数字: 10, 字符串: Hello (换行) |
fmt.Fprint | 将一系列值输出到实现了io.Writer 接口的对象,值之间无分隔符,不自动换行 | file, _ := os.Create("output.txt") fmt.Fprint(file, "Hello", "World") file.Close() | 在output.txt 文件中写入HelloWorld |
fmt.Fprintln | 将一系列值输出到实现了io.Writer 接口的对象,值之间用空格分隔,最后自动换行 | file, _ := os.Create("output.txt") fmt.Fprintln(file, "Hello", "World") file.Close() | 在output.txt 文件中写入Hello World (换行) |
fmt.Fprintf | 按照格式化字符串指定的格式将值输出到实现了io.Writer 接口的对象 | file, _ := os.Create("output.txt") fmt.Fprintf(file, "数字: %d, 字符串: %s", 10, "Hello") file.Close() | 在output.txt 文件中写入数字: 10, 字符串: Hello |
fmt.Scan | 从标准输入读取数据,按照空白字符(空格、制表符、换行符等)分隔输入值,并将读取的值存储到指定的变量中 | var num int fmt.Scan(&num) fmt.Println(num) 假设输入 10 ,则输出10 (换行) | 用户输入10 后,输出10 (换行) |
fmt.Scanln | 从标准输入读取数据,读取到换行符结束,并将读取的值存储到指定的变量中 | var str string fmt.Scanln(&str) fmt.Println(str) 假设输入 Hello World ,则输出Hello World (换行) | 用户输入Hello World 并回车后,输出Hello World (换行) |
fmt.Sscanf | 从字符串中按照格式化字符串指定的格式读取数据,并将读取的值存储到指定的变量中 | str := "10 Hello" var num int var s string fmt.Sscanf(str, "%d %s", &num, &s) fmt.Printf("数字: %d, 字符串: %s", num, s) | 数字: 10, 字符串: Hello |
以上表格涵盖了fmt
包中较为常用的函数。需要注意的是,在实际使用fmt.Scan
系列函数时,要确保输入的格式与期望的格式一致,否则可能导致程序出现意外行为。同时,对于涉及文件操作的fmt.F*
系列函数,要注意处理可能出现的错误,如文件创建、打开、关闭失败等情况。
四、实战:综合案例(变量+函数+数据类型)
我们来写一个简单的学生成绩管理小功能,包含“录入成绩”和“计算平均分”两个函数,巩固今天的知识点:
package mainimport "fmt"// 1. 录入学生成绩(返回成绩列表)
func inputScores() []int { // []int表示返回整数切片(暂时理解为动态数组)var n intfmt.Print("请输入学生人数:")fmt.Scan(&n) // 从控制台读取输入scores := make([]int, n) // 创建一个能存n个整数的切片for i := 0; i < n; i++ {fmt.Printf("请输入第%d个学生的成绩:", i+1)fmt.Scan(&scores[i])}return scores
}// 2. 计算平均分(接收成绩列表,返回平均分)
func calcAverage(scores []int) float64 {sum := 0for _, score := range scores { // 遍历成绩列表sum += score}// 注意:整数/整数默认是整数,需要转成float64算小数return float64(sum) / float64(len(scores))
}func main() {fmt.Println("===== 学生成绩系统 =====")scores := inputScores() // 调用函数录入成绩avg := calcAverage(scores) // 调用函数计算平均分fmt.Printf("平均分:%.2f分\n", avg) // 保留2位小数输出
}
运行效果:
===== 学生成绩系统 =====
请输入学生人数:3
请输入第1个学生的成绩:90
请输入第2个学生的成绩:85
请输入第3个学生的成绩:95
平均分:90.00分
五、小结与练习
今天我们学了Go的核心基础:
- 变量:用
var
或:=
声明,是存储数据的“盒子”; - 数据类型:整数、浮点、布尔、字符串、字符,各有适用场景;
- 函数:用
func
定义,能封装功能,支持多返回值(Go的一大特色)。
课后练习:
- 写一个函数,接收两个整数,返回它们的和、差、积、商;
- 定义一个字符串变量,存储你的名字,用函数打印出“你好,XXX!”。
动手敲代码才是掌握的关键,有问题欢迎在评论区交流~
专栏预告:下一篇我们将学习Go进阶:流程控制(if/for/switch)与数组切片,带你学会代码的“逻辑控制”,写出更复杂的功能! 😊