参考文档:https://www.runoob.com/go/go-for-loop.html
一.环境配置
1.下载安装包
https://go.dev/dl/
双击安装后,会自动配置环境变量
二.go语言基础
1.关键字或保留字25
break,default,func,interface,select,case,defer,go,map,struct,chan,else,goto,package,switch,
const,fallthrough,if,range,type,continue,for,import,return,var
2.预定义标识符
append,bool,byte,cap,close,complex,complex64,complex128,uint16,copy,false,float32,float64,
imag,int,int8,int16,unit32,int32,int64,iota,len,make,new,nil,panic,unit64,print,println,real,
recover,string,true,uint,uint8,uintptr
3.数据类型
boolean型: bool true false
int8 & float32
字符串类型
派生类型:
指针类型(Pointer),数组类型, 结构化类型(struct),Channel类型, 函数类型, 切面类型, 接口类型(interface),Map(类型)
4.demo
package main
import (
"fmt"
)
/*
func init() {
fmt.Println("init 动次打次")
}
*/
func main() {
//var aaa = "世界666"
//fmt.Println("hello word" + aaa)
//fmt.Println("第二句话")
add := mathClass.Add(1, 2)
//fmt.Println(add)
//fmt.Println(mathClass.Sub(10, 9))
//var faa = "%s在唱歌,%s在玩游戏"
//fmt.Printf(faa, "张三", "李四")
//test()
t1()
}
func test() {
var x int = 5
var y = "5"
if 1 < x {
fmt.Println("1小于x")
}
fmt.Print(x)
fmt.Println("啦啦啦" + y)
}
func t1() {
var fuShu = 1.2
var flag bool = false
fmt.Println(fuShu)
fmt.Println(flag)
}
5.变量声明
第一种,指定变量类型,如果没有初始化,则变量默认为零值
第二种,根据值自行判定变量类型
第三种,如果变量已经使用 var 声明过了,再使用 := 声明变量,就产生编译错误
// 这种不带声明格式的只能在函数体中出现
intVal := 1 相等于:
var intVal int
intVal =1
_ 空白标识符, 可用于遗弃某些值
func main() {
_,numb,strs := numbers() //只获取函数返回值的后两个
fmt.Println(numb,strs)
}
//一个可以返回多个值的函数
func numbers()(int,int,string){
a , b , c := 1 , 2 , "str"
return a,b,c
}
局部变量:在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
全局变量:在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。
注意:
1.局部变量不会一直存在,在函数被调用时存在,调用结束后死亡
2.全局变量可以与局部变量同名,同名时函数内的局部变量被优先考虑
6.值类型和引用类型
- 可以使用&获取变量的内存地址 如 &i // 返回 0xf840000040
- 值类型:基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值,值类型变量的值存在堆中
-
i =7; j =i; // 当使用等号=将一个变量的值赋给另一个变量时,实际上是在内存中将i的值进行了拷贝
- 引用类型:一个引用类型变量R1存储的是r1的值所在的内存地址,或内存地址中第一个字所在的位置,这个内存地址 称为指针
- 当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。
- 如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响。
7.常量
- 常量数据类型只能是:布尔,数字,字符串
- 被const 修饰的变量就是常量
-
func t5() { const ( b = "2" //a = iota c = "王五" d e f = iota ) const name = "李四" // fmt.Println(name) fmt.Println(b, c, d, e, f) } // 打印如下 2 王五 王五 王五 4
- iota 是特殊常量,在const中使用时,编译器会自动在第一行内容初始化iota的值为0,每增加一行就会自动加1,相当于行的计数器
- demo
-
package main import "fmt" const ( i=1<<iota j=3<<iota k l ) func main() { fmt.Println("i=",i) fmt.Println("j=",j) fmt.Println("k=",k) fmt.Println("l=",l) } // 运行结果如下 i= 1 j= 6 k= 12 l= 24
- 以上例子说明 k,l 省略的是编译前的表达式,而不是表达式执行的值
8.运算符
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 其他运算符
- 优先级
9.条件语句
- if else
- switch case支持多条件,默认自带break, fallthrough 继续执行下面的case,也可用 break 终止,allthrough 不会判断下一条 case 的表达式结果是否为 true。
default 不论放在哪都是最后执行func t6() { var mark = 90 var grade = "" switch mark { case 90: grade = "A" case 70: grade = "B" case 60, 65, 68: grade = "C" default: grade = "D" } fmt.Println(grade) switch { case grade == "A": fmt.Println("优秀") fallthrough case grade == "B": fmt.Println("良好") default: fmt.Println("不优秀") } } // 执行结果 A 优秀 良好
- select
- select语句只能用于通道操作,每个case必须是一个通道操作,要么是发送要么是接受
- select语句会监听所有指定的通道上的操作,一旦其中一个通道准备就绪就会执行响应的代码块
- 如果多个通道准备就绪,会随机选择一个通道执行
- 如果所有通道都没准备好,就执行default中代码
- 如果没有default语句 select将阻塞直到某个通道可以运行
-
func t7() { c1 := make(chan string) c2 := make(chan string) go func() { time.Sleep(1 * time.Second) c1 <- "one" }() go func() { time.Sleep(2 * time.Second) c2 <- "two" }() for i := 0; i < 2; i++ { select { case msg1 := <-c1: fmt.Println("received-", msg1) case msg2 := <-c2: fmt.Println("received--", msg2) } } }
10.循环语句
- 例
func t9() { a := 3 // 相当于 while for a > 2 { fmt.Println("条件循环") } for i := 0; i < 6; i++ { fmt.Println("一二一", i) } // 相当于 for(;;) for { fmt.Println("死循环") } }
func t11() { arr := []string{"google", "runoob"} for i, i2 := range arr { fmt.Println(i, i2) } } // 打印结果 0 google 1 runoob
- 控制语句
- break 用于循环语句中跳出循环或跳出switch语句;在多重循环中,可以用标号 label 标出想 break 的循环
- continue 跳过当前循环剩余的语句,继续进行下一轮循环。(跳过本次循环)
- goto 讲控制转移到被标记的地方的语句
- return 用于立即终止当前的函数执行
11.函数
- 例
// 多入参 func t13(n1, n2 int) int { var result int // 需要声明临时变量 直接返回n1 或者n2 会报错 if n1 > n2 { result = n1 } else { result = n2 } return result } // 多返回 func t14() (int, int) { a := 10 b := 9 a, b = b, a return a, b } // 函数式入参 func t15() { // 声明函数变量 f := func(x float64) float64 { return math.Sqrt(x) } fmt.Println("开方么 ", f(25)) }
- go语言默认使用值传递,在调用过程中不会影响到实际参数
- 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数
- 引用传递:指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数进行的修改,将回影响到实际参数
- 函数式入参:函数可当入参传递给其他的函数
- 闭包:闭包就是匿名函数
12.方法
13.变量作用域
- 局部变量:函数体内声明的变量,作用域只在函数体内,参数和返回值变量也是局部变量
- 形参作为函数的局部变量来使用
- 全局变量:在函数体外声明的变量,作用域是整个包甚至外部包(被导出之后)
14.数组
- 声明之后,数组每位的默认值为0
- 例
// 声明 var arr [10]int // 初始化 var arr1 = [10]int{2, 2, 3, 3, 4, 4} arr2 := [5]int{5, 6, 7, 8}