初识Go语言
1.我的基础
学过c,python,上手感觉语法差别不是很大。学到管道那里感觉有点陌生,不过之前学操作系统的时候大概学过一些,sleep等操作也比较熟悉。
2.环境配置
官网下载GO,配置vscode插件,还挺快的。 不过发现AI练中学非常方便就改用AI练中学了。
AI练中学的优点
1.文件目录清晰,模块明确 2.便于学习和复习翻阅。
go语言学习
hello world
$ go run hello-world.go
$ go build hello-world.go
$ ./hello world
go代码可以被构建为二进制文件
values数据类型
Go语言的数据类型可以分为以下几类:(来自豆包)
-
基本数据类型:
-
布尔型(bool):用于表示逻辑值,只有两个可能的值:true 和 false。
-
数值类型:
- 整数类型(int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64):用于表示整数,不同类型的整数有不同的取值范围。
- 浮点类型(float32、float64):用于表示实数,float32 是单精度浮点数,float64 是双精度浮点数。
- 复数类型(complex64、complex128):用于表示复数,complex64 是由两个 float32 组成的复数,complex128 是由两个 float64 组成的复数。
-
字符串类型(string):用于表示文本数据。
-
-
派生数据类型:
- 指针类型(pointer):用于表示内存地址。
- 数组类型(array):用于表示一组相同类型的元素。
- 切片类型(slice):是对数组的引用,可以动态增长或缩小。
- 映射类型(map):是一种无序的键值对集合。
- 结构体类型(struct):是一种自定义的数据类型,可以包含不同类型的字段。
- 接口类型(interface):用于定义一组方法的签名,任何实现了这些方法的类型都可以被视为该接口的实例。
- 函数类型(function):用于表示函数,可以作为参数传递或返回值。
- 通道类型(channel):用于在 goroutine 之间进行通信。
以上是 Go 语言的主要数据类型,每种类型都有其特定的用途和特点。在编写 Go 代码时,需要根据实际需求选择合适的数据类型。
var声明变量
package main
import "fmt"
func main() {
var a = "initial"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
var d = true
fmt.Println(d)
var e int
fmt.Println(e)
f := "apple"
fmt.Println(f)
}
未初始化的变量有默认值0 一次可以声明多个变量 :=是声明变量的简写方式,只能在函数内部使用
constants常量
const语句可以出现在var语句可以出现的任何地方。
for循环
是go语言唯一的循环结构。
分支-判断
if-else 用法熟悉,略 switch 用法熟悉,略
array数组
同样从0计数,可以切片,可以创建多维数组。 ` package main
import "fmt"
func main() {
var a [5]int
fmt.Println("emp:", a)
a[4] = 100
fmt.Println("set:", a)
fmt.Println("get:", a[4])
fmt.Println("len:", len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println("dcl:", b)
b = [...]int{1, 2, 3, 4, 5}
fmt.Println("dcl:", b)
b = [...]int{100, 3: 400, 500}
fmt.Println("idx:", b)
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
twoD = [2][3]int{
{1, 2, 3},
{1, 2, 3},
}
fmt.Println("2d: ", twoD)
}
运行结果
$ go run arrays.go
emp: [0 0 0 0 0]
set: [0 0 0 0 100]
get: 100
len: 5
dcl: [1 2 3 4 5]
dcl: [1 2 3 4 5]
idx: [100 0 0 400 500]
2d: [[0 1 2] [1 2 3]]
2d: [[1 2 3] [1 2 3]]
切片操作:
s := []string{"a","b","c","d","e","f","g"}
l := s[2:5]
fmt.Println("sl1:", l)
切片结果
sl1:[c d e]
map
类似python的dict字典
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
map即为键值对合集
range
同python一样,左闭右开。
func函数
Go需要显式返回,也就是说,它不会自动返回最后一个表达式的值。 当有多个连续的相同类型的参数时,可以省略类似类型的参数的类型名称,直到声明该类型的最后一个参数为止。
func plus(a int, b int) int {
return a + b }
variadic可变传入值函数
` package main
import "fmt"
func sum(nums ...int) { fmt.Print(nums, " ") total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
func main() {
sum(1, 2)
sum(1, 2, 3)
nums := []int{1, 2, 3, 4}
sum(nums...)
} ` 运行结果
$ go run variadic-functions.go
[1 2] 3
[1 2 3] 6
[1 2 3 4] 10
形参和返回值的数据类型都会预先声明。
注意,go语言的函数可以有多个返回值。
如果只需要返回值的子集,要使用空标识符_。
closures匿名函数
package main
import "fmt"
func intSeq() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
newInts := intSeq()
fmt.Println(newInts())
}
recursion递归
熟悉的内容,略
point指针
函数可以进行传值引用,也可以进行传址引用。 将一个值复制到一个解引用的指针会改变被引用地址的值。 &i语法给出了i的内存地址,即指向i的指针。 在go中,可以为一个参数创建无数个指针。Go语言允许你传递指针作为函数参数,这样可以在函数内部修改原始数据的值。 在Python中,变量实际上是对象的引用(或指针),而不是内存地址。你实际上是在传递这个变量所引用的对象的指针。
Strings and Runes
在go中,字符串不是以数个字符连接而成的,而是以数个字节连接的。 一个字符可能跨越多个字节。 ` package main
import ( "fmt" "unicode/utf8" )
func main() {
const s = "สวัสดี"
fmt.Println("Len:", len(s))
for i := 0; i < len(s); i++ {
fmt.Printf("%x ", s[i])
}
fmt.Println()
fmt.Println("Rune count:", utf8.RuneCountInString(s))
for idx, runeValue := range s {
fmt.Printf("%#U starts at %d\n", runeValue, idx)
}
fmt.Println("\nUsing DecodeRuneInString")
for i, w := 0, 0; i < len(s); i += w {
runeValue, width := utf8.DecodeRuneInString(s[i:])
fmt.Printf("%#U starts at %d\n", runeValue, i)
w = width
examineRune(runeValue)
}
}
func examineRune(r rune) {
if r == 't' {
fmt.Println("found tee")
} else if r == 'ส' {
fmt.Println("found so sua")
}
} ` 运行结果
休息
今天先到此为止了。事已至此,先吃饭吧。