//-- Go语言知识点一、Go语言的变量、常量、标识符、关键字、数据类型、类型转换、类型别名;Ps:从变量的组成上回忆知识点
//-- Go语言知识点二、Go语言的运算符(算数、逻辑、位、赋值、比较、*&、Scanf Printf)
//-- Go语言知识点三、Go语言的流程控制 顺序、选择、循环(特殊家的for _, s := range str ,来遍历字符串、数组、切片、map 以及 channel );除此还有配合的 break continue goto return语句
//-- Go语言知识点四、Go语言的函数(与C不同之处是返回任意多个值,像js一样) 函数名 函数的参数(有…表示为可变参数) 函数的返回值 函数体和返回语句,以及声明函数的关键字func,以及函数类型
//-- 1.函数的可变参数除了可以支持指定任意的个数,还可以支持任意的数据类型 。
//-- 2.函数变量与函数类型: 声明了一个类型是 func 的函数变量 f 即 var f func(), 那么f就是函数变量,函数的类型就是 func(), 如果有参数和返回值则可添加参数和返回值。
//-- 3.函数名: 有一种匿名函数,匿名函数可以作为一种类型被赋值给函数类型的变量。匿名函数末尾加()或者加(函数实参)即时调用匿名函数。此外匿名函数还可以作为函数的参数,用作回调。
//-- 4.函数的闭包功能: 就是一个返回值是一个(匿名)函数类型的函数中套了一个匿名函数,被套的匿名函数被返回。别人的解释:在 Go 语言中,被捕获到闭包中的变量让闭包本身拥有了记忆效应,闭包中的逻辑可以修改闭包捕获的变量,变量会跟随闭包生命期一直存在,闭包本身就如同变量一样拥有了记忆功能。
//-- 5.函数内的defer语句,自我理解,采用压栈的方式,后进先出。多用于函数调用完毕后,释放资源用的。(或者好多分支 的最后都有相同的语句,可以使用一条defer语句即可)如果同一个 函数 中,既有 defer 语句,同时也有 return 语句,那么 defer 语句会在 return 语句的后面执行。
//-- 6.函数的返回值特殊之处:返回方式之一:(给返回值变量赋值之后,一定要记得加 return 语句)
//-- 7.函数的递归, 自己调自己+终止条件
//-- 8.函数的错误处理: 利用返回值(它不像C++有异常处理机制)
//-- 9.函数内可以使用panic方式终止程序的运行
//-- 10.Golang 中的 recover 一般都是配套 defer 一起使用,使用异常恢复,即 recover。
//-- 例如
// func f() {
// defer func() {
// fmt.Println(“defer start”)
// if err := recover(); err != nil {
// fmt.Println(err)
// }
// fmt.Println(“defer end”)
// }()
// for {
// fmt.Println(“func begin”)
// a := []string{“a”, “b”}
// fmt.Println(a[3])
// panic(“bug”)
// fmt.Println(“func end”)
// time.Sleep(1 * time.Second)
// }
// }
//-- 11.统计函数执行时间 start := time.Now() elapsed := time.Since(start)
//-- 12.main函数,无参,无返回值的程序入口函数。在他之前只有init函数提前执行。
//-- 13.在main函数里面,获取命令行参数 os.Args; 通过 len(os.Args) 可以获取命令行参数的个数
//-- 14.在main函数里面,获取命令行参数 还可以通过 flag 包相关的 函数 来获取。
//-- 15.Go 语言程序每一个源文件都可以包含一个 init 函数,该函数会在 main 函数之前执行,被 Go 语言框架调用,也就是说 init 会在 main 函数之前被调用。如果一个文件同时包含全局变量定义
//-- Go语言知识点五、Go语言的string,也就是字符串的操作 下文只举例了几个,关于字符串的操作请见https://haicoder.net/golang/golang-string-map.html
//-- 关于时间
var timeBegin int64 = 0
func clacTime(isBegin bool) {
t := time.Now()
if isBegin {
//-- 全局变量要避免的坑:例如定义了一个全局变量, 然后有使用了 := 给全局变量赋值, 此时会出现问题。
//timeBegin := t.UnixNano() / 1e6
timeBegin = t.UnixNano() / 1e6
fmt.Printf("开始时间戳(毫秒):%v;\n", timeBegin)
} else {
timeEnd := t.UnixNano() / 1e6
fmt.Printf("结束时间戳(毫秒):%v;\n", timeEnd)
//fmt.Printf("开始时间戳(毫秒123):%v;\n", timeBegin)
fmt.Printf("开始结束时间戳时间间隔(毫秒):%v;\n\n", timeEnd-timeBegin)
fmt.Printf("开始结束时间戳时间间隔2(毫秒):%v;\n\n", time.Since(t))
}
fmt.Println("---4---", t)
fmt.Printf("时间戳(秒):%v;\n", t.Unix())
fmt.Printf("时间戳(纳秒):%v;\n", t.UnixNano())
fmt.Printf("时间戳(毫秒):%v;\n", t.UnixNano()/1e6)
fmt.Printf("时间戳(纳秒转换为秒):%v;\n", t.UnixNano()/1e9)
}
//-- 关于部分操作符
func excapeCharater() {
//-- 制表符
fmt.Println("Hello \t嗨客网(www.haicoder.net)")
fmt.Println("Hello \tHaiCoder")
//-- 转义符
fmt.Println("Hello \\HaiCoder")
fmt.Println("Hello \"HaiCoder")
}
//-- 关于数据类型和流程控制
//func testDataType(string []modules) {
func testDataType(modules []string) {
//引用类型: 切片、map、channel、interface 和函数类型。
modules[2] = "abc"
//println("In modules = %v, &modules= %p \n", modules, modules)
fmt.Printf("In modules = %v, &modules= %p \n", modules, modules)
//-- Go 语言的 int 类型的具体大小是跟机器的 CPU 位数相关的。如果 CPU 是 32 位的,那么 int 就占 4 字节,如果 CPU 是 64 位的,那么 int 就占 8
//-- Go 语言的复数类型
var score complex64 = complex(1, 2)
var number complex128 = complex(23.23, 11.11)
fmt.Print("Real Score = ", real(score), " Image Score = ", imag(score), "\n")
fmt.Print("Real Number = ", real(number), " Image Number = ", imag(number), "\n")
//-- Go语言的字符类型
var c1 byte = 'a'
var c2 byte = '0'
fmt.Println("C1 = ", c1, "C2 = ", c2)
fmt.Printf("C1 = %c, C2 = %c\n", c1, c2)
//-- Go语言的bool
var isOk bool
var isOnline = true
fmt.Println("IsOk = ", isOk, "IsOnline = ", isOnline)
//-- Go 语言的字符串,双引号和反引号。 反引号可以原样输出, 在数据库建表时候的特殊set 字段是使用反引号
var name string = "Hello \"HaiCoder\""
var site = `Hello
"HaiCoder"`
fmt.Println("Name = ", name)
fmt.Println("Site = ", site)
//-- Go语言的指针类型
var score2 int32 = 99
var pScore *int32 = &score2
var scoreVal = *pScore
fmt.Println("Score = ", score2, "PScore =", pScore, "ScoreVal =", scoreVal)
//-- 类型转换
//-- 标识符 print real byte bool 关键字chan go defer map
//-- 语言常量生成器 itoa
const mk int = 2
fmt.Printf("mk = %d, mk type = %T\n", mk, mk)
//const mk2 int = itoa
const mk2 int = iota
// const (
// Sunday int = iota
// Monday
// Tuesday
// Wednesday
// Thursday
// Friday
// Saturday
// )
//-- 类型别名
type Error = int
var err Error
err = 10001
fmt.Printf("err = %d, err type = %T\n", err, err)
//-- Go语言遍历切片和数组
// 使用for range遍历切片,忽略key
var slice = make([]string, 0, 3)
slice = append(slice, "Hello")
slice = append(slice, "嗨客网")
slice = append(slice, "HaiCoder")
for _, value := range slice {
fmt.Println("使用for range遍历切片,忽略key:", value)
}
// 使用for range遍历数组,忽略key
var str [3]string
str[0] = "Hello"
str[1] = "嗨客网"
str[2] = "HaiCoder"
for _, val := range str {
fmt.Println("使用for range遍历数组,忽略key:", val)
}
// 使用for range遍历 map
var data = make(map[string]string, 3)
data["module"] = "Server"
data["category"] = "Python"
data["site"] = "HaiCoder"
for key, value := range data {
fmt.Println(key, "================>", value)
}
}
//-- 变量的声明方式2
var (
a int = 45
b string = "heiha"
c []float32 = []float32{123.125444444, 555.55544445, 858.114114144} //-- 切片, 相当于数组
d func() bool
e bool = false
)
//-- func关键字 函数名,函数参数, 函数的返回值
func foo(a int) (ab int, cd int) {
ba := 91 + a
return ba, ba + 1
}
//-- 关于defer的用法
var y = 0 //全局变量
func increment(wg *sync.WaitGroup, x int, i int) {
y = y + 1 //访问全局变量
x = x + 10000 + i //访问局部变量
defer wg.Done()
if 19999 == x {
fmt.Println(x)
}
}
func testGroupRotine() {
clacTime(false)
var w sync.WaitGroup
for i := 0; i < 10000; i++ {
w.Add(1)
var x int
//var k int64
k := i
go increment(&w, x, k)
if i == 9999 {
fmt.Println("i=9999")
}
}
w.Wait()
fmt.Println("final value of x", y) //结果不确定
}
func GoStringTest() {
//-- Go语言字符串的操作
str1 := "Hello World"
var d int
//-- 1.字符串切片string[begin:end]其区间为[begin, end)
fmt.Println("str1[0:2] = ", str1[0:2])
//-- 2.字符串拼接有5种,除 + 和 sprintf还有3种。(记不过来 自己去查吧)join等
fmt.Println("str1[0:2] + str1= ", str1[0:2]+str1)
str1 = fmt.Sprintf("%s%d%s", str1, d, str1)
fmt.Println("str1 =", str1)
//-- 3.字符串长度的四种方法。(记不过来 自己去查吧)utf8.RuneCountInString() strings.Count()
var type1 int
if type1 == 1 {
//-- 得到的长度是字符串的长度+1
strCount := bytes.Count([]byte(str1), nil)
fmt.Println("strCount =", strCount)
} else {
//使用 len() 获取字符串长度
strHaiCoder := "嗨客网(Hello, HaiCoder)"
strCount := len(strHaiCoder)
strCount2 := len([]rune(strHaiCoder))
fmt.Println("strCount =", strCount, "strCount2 =", strCount2)
}
//-- 4.字符串的分割(按照空格、字符串、字符分割)
//-- 5.统计字符以及字符串出现的次数 strings.Count(strHaiCoder, "Golang")
//-- ......还有很多略去
}