本文共 5840 字,大约阅读时间需要 19 分钟。
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。
语法:
var variable_name [SIZE] variable_type
实例:
var balance [10] float32
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
如果数组长度不确定,可以使用 … 代替数组的长度,编译器会根据元素个数自行推断数组的长度:
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}或者balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
a1 := [...]int{ 1, 3, 5, 7, 8}for index, value := range a1 { other := 9 - value for index2 := index + 1; index2 < len(a1); index2++ { if a1[index2] == other { // 另一半在数组中,把它们的索引打印出来 fmt.Printf("它们的索引是:(%d %d)\n", index, index2) } } }
完整实例:
package mainimport "fmt"// 1. 定义一个数组[1,3,5,7,8],求数组中所有元素的和func main() { a1 := [...]int{ 1, 3, 5, 7, 8} fmt.Println(a1) // // 1. 数组求和 // sum := 0 // // := 相当于声明变量并且赋值 // for _, v := range a1 { // // fmt.Println(v) // sum = sum + v // } // fmt.Println(sum) // 2. 找出数组中和为指定值的两个元素的下标,比如从数组[1,3,5,7,8]中找出和为8的两个元素的下标分别为(0,3)和(1,2)。 // 遍历数组, // 2.1依次取出每个元素 // 2.2 计算一下 other= 8-当前值 // 2.3 在不在数组中,在的话把索引拿出来 // [1, 3, 5, 7, 8] for index, value := range a1 { other := 9 - value for index2 := index + 1; index2 < len(a1); index2++ { if a1[index2] == other { // 另一半在数组中,把它们的索引打印出来 fmt.Printf("它们的索引是:(%d %d)\n", index, index2) } } }}
语法:
var 数组名 [大小][大小]类型
比如:
var b [3][2]intb = [3][2]int{ [2]int{1, 2}, [2]int{3, 4},}
声明同时赋值:
var c = [3][2]int{ {1, 2}, {3, 4}, {5, 6}, }
多维数组遍历:
for i := 0; i < len(d); i++ { for j := 0; j < len(d[i]); j++ { fmt.Printf("%d-%d\n", i, d[i][j]) } }
切片和数组相似,它们都是保存相同数组类型元素的容器,但是切片的元素个数是可变的, 数组不可变
切片不需要明确指定元素的个数
1.方式一:
var s []int //创建int类型切片var s []string //创建string类型切片
2.通过 make() 函数创建切片:
slice := make([]int, 5)
内部实现:
切片是一个很小的对象,它对底层的数组(内部是通过数组保存数据的)进行了抽象,并提供相关的操作方法;
切片是有三个字段的数据结构,这些数据结构包含Go语言需要操作底层数组的元数据
使用append可以往切片里添加元素:
var a = []int{} //空切片a = append(a, 1)
Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
声明map类型
var m1 map[string]int //未初始化就是 nil
使用make初始化map
m1 = make(map[string]int, 100) m1["nazha"] = 90 m1["haojie"] = 100
声明map类型时直接初始化
m2 := map[string]string{ "haojie": "hehe", "yawei": "heihei", }
遍历键值对
for k, v := range m2 { fmt.Println(k, v) }
遍历键
for k := range m2 { fmt.Println(k) }
判断map中是否存在某个键值对
v, ok := m2["haojie"] // ok返回的是布尔值,能取到就返回true,取不到就返回false if !ok { fmt.Println("查无此人") } else { fmt.Println(v) }
删除键值对
delete(m2, "haojie")
初始化切片
mapSlice := make([]map[string]int, 3, 10)
添加元素
mapSlice = append(mapSlice, map[string]int{"aaa": 10})mapSlice = append(mapSlice, map[string]int{"bbb": 100})
对外层的map做初始化
sliceMap := make(map[string][]int, 10)
对map的值(切片)做初始化
sliceMap["haojie"] = make([]int, 3, 10)sliceMap["haojie"][0] = 1sliceMap["haojie"][1] = 2sliceMap["haojie"][2] = 3
Go 语言函数定义格式如下:
func function_name( [parameter list] ) [return_types] {函数体}
函数定义解析:
没有参数没有返回值的函数
func sayHello() { fmt.Println("Hello 沙河!")}
带参数的函数
func sayHi(name string) { fmt.Printf("Hello %s\n", name)}
带参数和返回值
func add(a int, b int) int {ret := a + breturn ret}
func add3(a, b int) (ret int) { ret = a + b return}
可变参数
func add4(a int, b ...int) int { ret := a fmt.Println(a) fmt.Printf("b=%v type:%T\n", b, b) for _, v := range b { ret = ret + v } return ret}
func add5() (int, int, int) { return 1, 2, 3}
函数可以作为变量、参数、返回值
package mainimport "fmt"// 函数可以作为变量、参数、返回值func add(a, b int) int { return a + b}func sub(a, b int) int { return a - b}// calc是一个函数,它接收三个参数,返回一个int类型的返回值// 其中,参数a和b是int类型// 参数f 是一个函数类型,这个函数接收两个int类型的参数,返回一个int类型的返回值func calc(a, b int, f func(int, int) int) int { return f(a, b)}func main() { f1 := add fmt.Printf("f1:%T\n", f1) fmt.Println(f1(10, 20)) //把add当成一个参数传进calc中 ret := calc(100, 200, add) fmt.Println(ret) // 把sub当成一个参数传进calc中 ret = calc(100, 200, sub) fmt.Println(ret)}
匿名函数
匿名函数由一个不带函数名的函数声明和函数体组成,如下所示:func(a,b int,z float64) bool{ return a*b }
package mainimport "fmt"// 匿名函数func main() { func() { fmt.Println("Hello world!") }() // 花括号后加()表示函数调用}
闭包函数,即在一个封闭作用域中的函数,这个函数可以使用封闭作用域中的所有变量。也就是使用该函数时除了函数中的变量(函数变量)还可以对闭包中的函数(自由变量进行操作)
示例一:
// 定义一个函数f1// f1不接受参数// f1返回一个函数类型,这个函数不接收参数也没有返回值func f1(num int) func(int) int { f := func(x int) int { fmt.Println("找到外层函数的变量num", num) return num + x } return f}
示例二:
func makeSuffixFunc(suffix string) func(string) string { return func(name string) string { if !strings.HasSuffix(name, suffix) { return name + suffix } return name }}
示例三:
func calc(base int) (func(int) int, func(int) int) { add := func(i int) int { base += i // 引用了外层的base变量同时还修改了base return base } sub := func(i int) int { base -= i return base } return add, sub}
Go语言的 defer 语句会将其后面跟随的语句进行延迟处理,在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。
package mainimport "fmt"func testDefer() { defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) fmt.Println("函数马上要结束了...")}func main() { testDefer()}
打印200~1000之间的质数(素数)
package mainimport "fmt"func main() { for i := 200; i < 1000; i++ { // fmt.Println(i) flag := true //判断i是否为质数,如果是就打印,如果不是就不打印 for j := 2; j < i; j++ { if i%j == 0 { //不是质数 flag = false break } } //整个第二层的for循环结束了还没有break说明是质数 if flag { fmt.Printf("%d是质数.", i) } }}
打印9*9乘法表
package mainimport "fmt"func main() { for i := 1; i < 10; i++ { for j := i; j < 10; j++ { fmt.Printf("%d*%d=%d\t", j, i, i*j) } fmt.Println() }}
转载地址:http://fzhzi.baihongyu.com/