package main import ( "fmt" "container/list" "rect"// 导入自定义包 "time" "sync" ) var a string = "阿里云大学" var b string = "edu.aliyun.com" //var c bool //全局变量是允许声明但不使用。 var aa, bb, cc int //多变量可以在同一行进行赋值,如 var aaa, bbb, ccc = 55, 77, "abc" const( // 定义每分钟的秒数 SecondsPerMinute = 60 // 定义每小时的秒数 SecondsPerHour = SecondsPerMinute * 60 // 定义每天的秒数 SecondsPerDay = SecondsPerHour * 24 ) // 结构体 type Employee struct { firstname,lastname string age, salary int } func main() { //常量 const LENGTH int = 10 const WIDTH int = 5 const cl1, cl2, cl3 = 1, false, "str" //多重赋值 var area int area = LENGTH * WIDTH // 变量 var c, d int = 1, 2 var e, f = 123, "hello" //如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a。 a, b = b, a g, h := 456, "lalala" // g 和 h 的类型(int 和 string)将由编译器自动推断。这是使用变量的首选形式,但是它只能被用在函数体内 // 计算 var ajs int = 21 var bjs int = 10 var cjs int cjs = ajs + bjs fmt.Printf("第一行 - cjs 的值为 %d ", cjs ) cjs = ajs - bjs fmt.Printf("第二行 - cjs 的值为 %d ", cjs ) //g, h := 456, "lalala" 这种不带声明格式的只能在函数体中出现 fmt.Println(a, b,c,d,e,f,g, h,&d) println(cl1, cl2, cl3) fmt.Printf ("常量为 cl1 = %d, cl3 = %s and area = %d ", cl1, cl3, area) //调用自定义函数 var ret int // 先定义一个变量,不然报错 ret = max(ajs, bjs) fmt.Printf( "最大值是 : %d ", ret) // 数组 // var n [10]int /* n 是一个长度为 10 的数组 */ var j int var balance = [5]float32{1000.1, 2.0, 3.4, 7.0, 50.0} fmt.Println(balance[0]) for j = 0; j < 5; j++ { fmt.Printf("shuzu:%f ", balance[j]) } //for range 语法上类似于其它语言中的 foreach 语句 // 打印索引和元素 for i, v := range a{ fmt.Printf("range打印数组%d %d ", i, v) } // 仅打印元素 for _, v := range a{ fmt.Printf("元素:%d ",v) } // for 循环 // 创建一个整型切片 // 其长度和容量都是 4 个元素 slice := []int{10, 20, 30, 40} // 从第三个元素开始迭代每个元素 for index := 2; index < len(slice); index++ { fmt.Printf("Index: %d Value: %d ", index, slice[index]) } /* 创建切片 */ numbers := []int{0,1,2,3,4,5,6} /* 打印原始切片 */ fmt.Println("numbers ==", numbers) /* 打印子切片从索引1(包含) 到索引4(不包含): 元素第一个索引为0*/ fmt.Println("numbers[1:4] ==", numbers[1:4]) // numbers[1:4] == [1 2 3] /* 默认下限为 0 :从0开始一直到索引为3 结束 */ fmt.Println("numbers[:3] ==", numbers[:3]) // numbers[:3] == [0 1 2] /* 默认上限为 len(s) 4 指的是索引 :从索引为4开始一直到最后 */ fmt.Println("numbers[4:] ==", numbers[4:]) // numbers[4:] == [4 5 6 7 8] //Go语言从切片中删除元素 //从开头位置删除 numbers = numbers[1:] // 删除开头1个元素 fmt.Println("del1 ==", numbers) //从中间位置删除 numbers = append(numbers[:3], numbers[4:]...) // 删除中间第4个元素 fmt.Println("del2 ==", numbers) // del1 == [1 2 3 4 5 6] del2 == [1 2 3 5 6] //从尾部删除 numbers = numbers[:len(numbers)-1] // 删除尾部1个元素 fmt.Println("del3 ==", numbers) //a = a[:len(a)-N] // 删除尾部N个元素 // 指定删除位置 定一个变量 index := 2 // 查看删除位置之前的元素和之后的元素 fmt.Println(numbers[:index], numbers[index+1:]) // 将删除点前后的元素连接起来 numbers = append(numbers[:index], numbers[index+1:]...) fmt.Println("del4 ==", numbers) // 区间 //fmt.Println(numbers[1:4]) // 中间到尾部的所有元素 //fmt.Println(numbers[3:]) // 开头到中间指定位置的所有元素 //fmt.Println(numbers[:3]) numbers1 := make([]int,0,5) printSlice(numbers1) /* 打印子切片从索引 2(包含) 到索引 5(不包含) */ number3 := numbers[2:5] printSlice(number3) /* 允许追加空切片 */ numbers = append(numbers, 7) fmt.Println("numbers ==", numbers) /* 同时添加多个元素 */ numbers = append(numbers, 8,9,10) fmt.Println("numbers ==", numbers) var numbers4 []int /* 同时添加多个元素 */ numbers4 = append(numbers4, 2,3,4) numbers4 = append(numbers4, 5) /* 创建切片 numbers1 是之前切片的两倍容量*/ numbers5 := make([]int, len(numbers4), (cap(numbers4))*2) //numbers5 = append(numbers5, 6) /* 拷贝 numbers 的内容到 numbers1 */ copy(numbers5,numbers4) printSlice(numbers5) aK, _ := GetData() // 100 _, bK := GetData() // 200 fmt.Println(aK, bK) // 直接声明新的切片 // 声明字符串切片 var strList []string // 声明整型切片 var numlist []int // 声明一个空切片 var numlistempty = []int{} // 输出3个切片 fmt.Printf("kongqiepian:%s = %d = %d ",strList, numlist, numlistempty) // 指针 var house = "zhizhenyinyong" ptr := &house // 打印ptr的类型 //fmt.Printf("ptr type: %T ", ptr) // 打印ptr的指针地址 //fmt.Printf("address: %p ", ptr) // 对指针进行取值操作 value := *ptr fmt.Printf("address: %p ", value) // 多维数组 // 声明一个二维整型数组,两个维度的长度分别是 4 和 2 var array[4][2]int // 使用数组字面量来声明并初始化一个二维整型数组 array = [4][2]int{{10,11}, {20,21}, {30,31}, {40,41}} // 声明并初始化数组中索引为 1 和 3 的元素 array = [4][2]int{1: {20, 21}, 3: {40, 41}} fmt.Println(array) // 创建一个整型切片,多维切片 slice2 := [][]int{{10}, {100, 200}} // 为第一个切片追加值为 20 的元素 slice2[0] = append(slice2[0], 20) fmt.Println(slice2) // map 映射,就是关联数组 var mapLit map[string]int mapLit = map[string]int{"one": 1, "two": 2} fmt.Println(mapLit) mapCreated := make(map[string]float32) //mapCreated := make(map[string]float)等价于mapCreated := map[string]float{} mapCreated["key1"] = 4.5 mapCreated["key2"] = 3.14159 mapCreated["key3"] = 5 /*fmt.Println(mapCreated["key2"]) */ // 如果需要特定顺序的遍历结果,正确的做法是先排序,代码如下: // 声明一个切片保存map数据 //var sceneList []string // 将map数据遍历复制到切片中 /*for k := range mapCreated { sceneList = append(sceneList, k) }*/ // 对切片进行排序 //sort.Strings(sceneList) // 输出 //fmt.Println(sceneList) //使用 delete() 函数从 map 中删除键值对 delete(mapCreated, "key2") for k, v := range mapCreated { fmt.Println(k, v) } // 初始化列表 方式1 list := list.New() // 初始化列表 方式2 //var list2 list2.List //双链表支持从队列前方或后方插入元素,分别对应的方法是 PushFront 和 PushBack。 // 尾部添加 list.PushBack("canon") // 头部添加 list.PushFront(67) // 尾部添加后保存元素句柄 element := list.PushBack("fist") // 在fist之后添加high list.InsertAfter("high", element) // 在fist之前添加noon list.InsertBefore("noon", element) // 使用 list.Remove(element) for i := list.Front(); i != nil; i = i.Next() { fmt.Println(i.Value) } // 遍历, 决定处理第几行 for y := 1; y<=9; y++ { // 遍历, 决定这一行有多少列 for x := 1; x<=y; x++ { fmt.Printf("%d*%d = %d ",x,y,x*y) } // 手动生成回车,打印一个空行,实际作用就是换行。 fmt.Println() } var sw = "hello" switch sw { case "hello": fmt.Println(1) case "world": fmt.Println(2) default: fmt.Println(3) } var r int = 11 switch { case r > 10 && r < 20: fmt.Println(r) } //冒泡排序 arr := [...]int{21,32,12,33,34,34,87,24} //让编译器为你自动计算数组长度,[5]int 和 [25]int 是不同类型 var n = len(arr) fmt.Println("--------没排序前-------- ",arr) for i := 0; i <= n-1; i++ { for j := i; j <= n-1; j++ { if arr[i] > arr[j] { t := arr[i] arr[i] = arr[j] arr[j] = t } // fmt.Println(arr) } } fmt.Println("--------最终结果-------- ",arr) // 将返回值作为打印参数 fmt.Println(resolveTime(1000)) // 只获取消息和分钟 _, hour, minute := resolveTime(18000) fmt.Println(hour, minute) // 只获取天 day, _, _ := resolveTime(90000) fmt.Println(day) var rectlen, rectwidth float64 = 6,7 ff := rect.Area(rectlen, rectwidth) fmt.Printf("area of rect %.2f ", ff) num := 11 if num % 2 == 0 { fmt.Println("the number is even") } else { fmt.Println("the number is odd") } for k :=1; k<=10; k++ { if k==5 || k==6 || k==7 { continue } fmt.Printf("%d",k) } var i int for{ if i>10{ fmt.Println(" dayu10") break } i++ } //精简for for i<=10{ fmt.Println(" 精简for") i++ } // 结构体 emp1 := Employee{ firstname: "sam", age: 25, salary: 500, lastname: "suibian", } emp2 := Employee{"firstlala", "lastlala", 29, 600} fmt.Println(" emp1:", emp1) fmt.Println("emp2:", emp2) //创建匿名结构体 emp3 := struct{ first1,fist2 string age int }{ first1: "niming1", fist2: "fist2", age: 31, } fmt.Println(" emp3:", emp3) //访问结构体的字段 fmt.Println(" first1:", emp3.first1) //调用别的包里的结构体 var spce rect.Spec spce.Maker = "apple" spce.Price = 666 fmt.Printf("rectbao%s,%d", spce.Maker,spce.Price) go hello() time.Sleep(1 * time.Second) fmt.Println(" main function ") //信道 // data := <- a // 读取信道 a //a <- data // 写入信道 a done := make(chan bool) //创建了一个 bool 类型的信道 done go hello2(done) //,并把 done 作为参数传递给了 hello 协程 <-done //我们通过信道 done 接收数据。这一行代码发生了阻塞,除非有协程向 done 写入数据, //否则程序不会跳到下一行代码。于是,这就不需要用以前的 time.Sleep 来阻止 Go 主协程退出了 //现在我们的 Go 主协程发生了阻塞,等待信道 done 发送的数据。该信道作为参数传递给了协程hello fmt.Println("xindao") //缓冲信道 ch := make(chan string, 2) ch <- "naveen" ch <- "paul" fmt.Println(<- ch) fmt.Println(<- ch) //WaitGroup no := 3 var wg sync.WaitGroup for i:=0; i<no; i++ { wg.Add(1) go process(i,&wg) } wg.Wait() fmt.Println("All go routines finished executing") //select 语句用于在多个发送/接收信道操作中进行选择 output1 := make(chan string) output2 := make(chan string) go server1(output1) go server2(output2) time.Sleep(4 * time.Second) select { case s1 := <-output1: fmt.Println(s1) case s2 := <-output2: fmt.Println(s2) default: fmt.Println("no value received") } } func server1(ch chan string) { time.Sleep(6 * time.Second) ch <- "from server1" } func server2(ch chan string) { time.Sleep(3 * time.Second) ch <- "from server2" } func process(i int, wg *sync.WaitGroup) { fmt.Println("started Goroutine ", i) time.Sleep(2 * time.Second) fmt.Printf("Goroutine %d ended ", i) wg.Done() } func hello() { fmt.Println(" Hello world goroutine ") } func hello2 (done chan bool) { // ,hello 打印出 Hello world goroutine fmt.Println("Hello world gxindao") //接下来向 done 写入数据。当完成写入时,Go 主协程会通过信道 done 接收数据, //于是它解除阻塞状态,打印出文本 xindao。 done <- true } // 将传入的“秒”解析为3种时间单位 func resolveTime(seconds int) (day int,hour int, minute int) { day = seconds / SecondsPerDay hour = seconds / SecondsPerHour minute = seconds / SecondsPerMinute return } /* 函数返回两个数的最大值 */ func max(num1, num2 int) int { /* 声明局部变量 */ var result int if (num1 > num2) { // 左大括号 { 一般不能单独放一行 result = num1 } else { result = num2 } return result } /*Go 语言指针*/ func zhizhen() { var zza int= 20 /* 声明实际变量 */ var ip *int /* 声明指针变量 */ ip = &zza /* 指针变量的存储地址 */ fmt.Printf("a 变量的地址是: %x ", &zza ) /* 指针变量的存储地址 */ fmt.Printf("ip 变量储存的指针地址: %x ", ip ) /* 使用指针访问值 */ fmt.Printf("*ip 变量的值: %d ", *ip ) } func printSlice(x []int){ fmt.Printf("len=%d cap=%d slice=%v ",len(x),cap(x),x) } func GetData() (int, int) { return 100, 200 }