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\n", cjs )
cjs = ajs - bjs
fmt.Printf("第二行 - cjs 的值为 %d\n", 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\n", cl1, cl3, area)
//调用自定义函数
var ret int // 先定义一个变量,不然报错
ret = max(ajs, bjs)
fmt.Printf( "最大值是 : %d\n", 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\n", balance[j])
}
//for range 语法上类似于其它语言中的 foreach 语句
// 打印索引和元素
for i, v := range a{
fmt.Printf("range打印数组%d %d\n", i, v)
}
// 仅打印元素
for _, v := range a{
fmt.Printf("元素:%d\n",v)
}
// for 循环
// 创建一个整型切片
// 其长度和容量都是 4 个元素
slice := []int{10, 20, 30, 40}
// 从第三个元素开始迭代每个元素
for index := 2; index < len(slice); index++ {
fmt.Printf("Index: %d Value: %d\n", 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\n",strList, numlist, numlistempty)
// 指针
var house = "zhizhenyinyong"
ptr := &house
// 打印ptr的类型
//fmt.Printf("ptr type: %T\n", ptr)
// 打印ptr的指针地址
//fmt.Printf("address: %p\n", ptr)
// 对指针进行取值操作
value := *ptr
fmt.Printf("address: %p\n", 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("--------没排序前--------\n",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("--------最终结果--------\n",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\n", 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("\ndayu10")
break
}
i++
}
//精简for
for i<=10{
fmt.Println("\n精简for")
i++
}
// 结构体
emp1 := Employee{
firstname: "sam",
age: 25,
salary: 500,
lastname: "suibian",
}
emp2 := Employee{"firstlala", "lastlala", 29, 600}
fmt.Println("\nemp1:", emp1)
fmt.Println("emp2:", emp2)
//创建匿名结构体
emp3 := struct{
first1,fist2 string
age int
}{
first1: "niming1",
fist2: "fist2",
age: 31,
}
fmt.Println("\nemp3:", emp3)
//访问结构体的字段
fmt.Println("\nfirst1:", 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("\nmain function\n")
//信道
// 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\n", i)
wg.Done()
}
func hello() {
fmt.Println("\nHello world goroutine\n")
}
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\n", &zza )
/* 指针变量的存储地址 */
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
/* 使用指针访问值 */
fmt.Printf("*ip 变量的值: %d\n", *ip )
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
func GetData() (int, int) {
return 100, 200
}