1.数据的输入和输出
1.1数据的输入
var num1, num2 int
fmt.Print("请输入两个整数,用空格分隔: ")
_, err := fmt.Scanln(&num1, &num2)
这里面的输入结果和c++和java有点不太一样 _指的是不在意读取的数据的个数,err指的是是否发生了错误
1.2 数据的输出
k:="apple"
fmt.Println(k)
2.变量的声明和赋值
有两种方式声明变量
var a = "initial"
k:="apple"
go语言的变量声明也和c++和java有些许不同,变量声明出来必须使用,如果不使用编辑器就会报错,无法编译
声明一个字符串变量但先不赋值
// 声明一个字符串变量
var str string
// 给字符串变量赋值
str = "Hello, World!"
// 声明一个字符变量
var ch rune
// 给字符变量赋值
ch = 'A'
3.for循环
go语言里面没有while循环,只有for循环 for循环示例
for j := 7; j < 9; j++ {
fmt.Println(j)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
和java和c++不太一样的地方在go语言里面for循环不需要括号,也不需要一定要写两个;,相当于用一个for通过充当了while和for的作用
4.if语句
示例
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
和c++和java一样,但是不用写括号了,还可以在if条件里面写变量的声明
5. switch语句
a := 2
switch a {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
case 4, 5:
fmt.Println("four or five")
default:
fmt.Println("other")
}
不需要在每一个case后面写break了,因为只会执行一次,而且switch里面的判断条件也更加丰富
6.数组
一维数组
//声明但是不赋值
var a [5]int
a[4] = 100
//声明且赋值
k:=[5]int{1,2,3,4,5}
fmt.Println(len(k))
二维数组
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
b:=[2][3]int{{1,2,3},{4,5,6}}
7.字符串
声明
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
//声明字符串数组 声明时不赋值
var a [4]string
a[0] = "a"
//声明字符串数组同时赋值
good := []string{"g", "o", "o", "d"}
库函数
strings.Contains: 检查一个字符串是否包含另一个字符串。strings.Count: 计算一个字符串在另一个字符串中出现的次数。strings.EqualFold: 比较两个字符串是否相等,忽略大小写。strings.Index: 返回一个字符串在另一个字符串中第一次出现的位置。strings.Join: 将一个字符串切片连接成一个字符串。strings.Repeat: 重复一个字符串指定的次数。strings.Replace: 替换一个字符串中的所有指定子串。strings.Split: 将一个字符串分割成字符串切片。strings.ToLower: 将一个字符串转换为小写。strings.ToUpper: 将一个字符串转换为大写。
8.map容器
声明一个map容器
m := make(map[string]int)
声明并对map容器初始化
m2 := map[string]int{"one": 1, "two": 2}
清除map容器的一个键值
delete(m, "one")
遍历map容器
// 使用range遍历map中的所有键值对
for key, value := range m {
fmt.Println(key, value)
}
判断map容器里面的键值是否存在
r, ok := m["unknow"]
fmt.Println(r, ok)
r, ok := m["unknow"] : 这是一个赋值语句,它使用了短变量声明和赋值操作符:=。这里发生了两件事:
r被赋值为从映射m中获取的值。如果键"unknow"存在,r将是对应的值;如果不存在,r将是int类型的零值0。
ok是一个布尔值,用于指示键"unknow"是否存在于映射m中。如果键存在,ok将被设置为true;如果键不存在,ok将被设置为false。
map容器里面键值的数量
fmt.Println(len(m));
9.range
遍历数组和容器
for i, num := range nums {
nums := []int{2, 3, 4}
sum := 0
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num) // index: 0 num: 2
}
}
//遍历容器
遍历map容器返回的键值对是无序的
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
//可以不是k,v,只需要是两个参数就可以
可以只遍历值,只需要用_来忽略键,示例如下 对于数组也同样适用
m := map[string]string{"a": "A", "b": "B"}
for _, v := range m {
fmt.Println( v) //B ; A
}
如果直接直接用一个变量去接受,就是遍历键 对于数组来说就是遍历值
m := map[string]string{"a": "A", "b": "B"}
for v := range m {
fmt.Println(v) // a; b
}
nums := []int{2, 3, 4}
sum := 0
for num := range nums {
sum += num
if num == 2 {
fmt.Println("num:", num) //num: 2
}
}
在通道(channel)上使用range
ch := make(chan int)
go func() {
ch <- 1
ch <- 2
ch <- 3
close(ch)
}()
for num := range ch {
fmt.Println(num)
}
10.函数
函数的声明 最重要的就是参数后置
func add(a int, b int) int {
return a + b
}
和c++和java不同的是,go语言的函数可以返回多个参数 在函数体里面,可以直接写return即可
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return
}
函数也可以接受可变参数,使用...符号
func sum(nums...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
匿名函数 可以在需要的地方使用匿名函数,不需要写函数的名字
func main() {
add := func(a, b int) int {
return a + b
}
fmt.Println(add(1, 2)) // 3
}
可以处理异常
Go语言中通常通过返回一个额外的错误类型参数来处理错误
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
//在go里面nil就是null的意思指没有错误
}
可以实现延迟调用 通过defer来实现在函数返回之前执行一些清理操作
func readFile(filename string) (string, error) {
file, err := os.Open(filename)
if err!= nil {
return "", err
}
defer file.Close() // 确保在函数返回前关闭文件
// 读取文件内容
//...
return "文件内容", nil
}
闭包函数
示例
func createCounter() func() int {
x := 0
return func() int {
x++
return x
}
}
func main() {
increment := createCounter()
fmt.Println(createCounter()) // 输出: 1
fmt.Println(createCounter()) // 输出: 2
fmt.Println(createCounter()) // 输出: 3
}
解释
-
createCounter函数:createCounter函数没有参数,它的目的是创建一个计数器。- 在函数内部,声明了一个局部变量
x,并初始化为0。 - 函数返回一个匿名函数,这个匿名函数没有参数,返回一个
int类型的值。
-
匿名函数(闭包) :
- 匿名函数内部的
x变量是对外部函数createCounter中x变量的引用。 - 每次调用这个匿名函数时,它会将
x的值加1,然后返回新的值。 - 由于
x是外部函数的局部变量,它的生命周期会随着闭包的存在而延长,即使外部函数createCounter已经返回。
- 匿名函数内部的
-
使用闭包:
- 在
main函数中,调用createCounter函数会返回一个计数器函数。 - 将这个计数器函数赋值给变量
increment。 - 每次调用
increment函数时,它会返回一个比上次调用时更大的整数。
- 在