做网站公司天津,淘宝联盟网站推广位怎么做,工程项目外包平台,免费小程序开发平台Go 数组Go 切片Go 变量和内存地址Go Map 类型Go 面向对象编程Go 方法的定义GO 数组数组是同一类型的元素集合。Go中的数组下标从0开始#xff0c;因此长度为n的数组下标范围是[0, n-1]。整数数组中元素默认初始化为0#xff0c;字符串数组中的元素默认初始化为。… Go 数组Go 切片Go 变量和内存地址Go Map 类型Go 面向对象编程Go 方法的定义GO 数组数组是同一类型的元素集合。Go中的数组下标从0开始因此长度为n的数组下标范围是[0, n-1]。整数数组中元素默认初始化为0字符串数组中的元素默认初始化为。 var a [3]int a[0] 10 a[1] 20 var a [3]int [3]int{10, 20, 30}//定义时数组初始化//数组初始化 var a [3]int [3]int{10, 20, 30}//定义时数组初始化a : [3]int{10, 20, 30}//定义时数组初始化a : [...]int{10, 20, 30}//定义时数组初始化 a : [3]int{10}//定义时数组初始化a : [3]int{2:10}//定义时数组初始化数组⻓度是类型的⼀部分var a [3]inta[0] 10a[1] 20a[2] 30var b [5]intba//a、b是不同类型的数组不能赋值len 内置函数var a [3]inta[0] 10a[1] 20a[2] 30fmt.Printf(“len:%d\n”, len(a))数组的遍历a. 下标进行遍历b. range 函数进行遍历range函数是个神奇而有趣的内置函数你可以使用它来遍历数组切片和字典。当用于遍历数组和切片的时候range函数返回索引和元素。当用于遍历字典的时候range函数返回字典的键和值。package mainimport fmtfunc main() { var a [3]int a[0] 10 a[1] 20 a[2] 30 // 使用下标遍历 for i : 0; i // fmt.Printf(a[i] ) } for index, val : range a { // fmt.Printf(a[i] ) } // 这里我们使用range来计算一个切片的所有元素和 // 这种方法对数组也适用 nums : []int{2, 3, 4} sum : 0 for _, num : range nums { sum num } fmt.Println(sum:, sum) // range 用来遍历数组和切片的时候返回索引和元素值 // 如果我们不要关心索引可以使用一个下划线(_)来忽略这个返回值 // 当然我们有的时候也需要这个索引 for i, num : range nums { if num 3 { fmt.Println(index:, i) } } // 使用range来遍历字典的时候返回键值对。 kvs : map[string]string{a: apple, b: banana} for k, v : range kvs { fmt.Printf(%s - %s\n, k, v) } // range函数用来遍历字符串时返回Unicode代码点。 // 第一个返回值是每个字符的起始字节的索引第二个是字符代码点 // 因为Go的字符串是由字节组成的多个字节组成一个rune类型字符。 for i, c : range go { fmt.Println(i, c) }}sum: 9index: 1a - appleb - banana0 1031 111Go数组排序Go 分别提供了sort.Float64s() sort.Strings() sort.Ints() 对不同类型的数组进行排序默认是升序。降序需要使用sort.Reverse。package mainimport (fmtsort)func main() { arrayInt : []int{3, 1, 2, 5, 4} arrayFloat : []float64{3.2, 1.8, 1.9, 2.2, 4.3} arrayString : []string{abc, ab, bc} // 升序 sort.Ints(arrayInt) sort.Float64s(arrayFloat) sort.Strings(arrayString) fmt.Println(sort int:, arrayInt) fmt.Println(sort float:, arrayFloat) fmt.Println(sort , arrayString) // 降序 sort.Sort(sort.Reverse(sort.IntSlice(arrayInt))) sort.Sort(sort.Reverse(sort.Float64Slice(arrayFloat))) sort.Sort(sort.Reverse(sort.StringSlice(arrayString))) fmt.Println(After reversed: ) fmt.Println(sort int:, arrayInt) fmt.Println(sort float:, arrayFloat) fmt.Println(sort , arrayString) }数组的拷贝和传参a. 数组是值类型var a [3]inta[0] 10a[1] 20a[2] 30b : a//b拷⻉了数组a中所有元素b[0] 1000a: [10,20,30]b: [1000,20,30]b. 数组是值类型函数传参也会拷⻉package mainimport (fmt)func main() { var a [3]int a[0] 10 a[1] 20 a[2] 30 modify(a) fmt.Println(a) // [10,20,30]}func modify(b [3]int) { b[0] 1000 fmt.Println(b) // [1000,20,30] return}GO 切片GO的切片是基于数组类型的一层封装。Go 数组的长度不可改变在特定场景中这样的集合就不太适用Go中提供了一种灵活功能强悍的内置类型切片(动态数组),与数组相比切片的长度是不固定的可以追加元素在追加时可能使切片的容量增大。 var a []int//定义⼀个int类型的空切⽚切⽚初始化, a[start:end]创建⼀个包括从start到end-1的切⽚。package mainimport (fmt)func main() { // 初始化方法1 a: [5]int{76, 77, 78, 79, 80} var b []int a[1: 4] //基于数组a // 创建⼀个切⽚包括元素a[1] a[2] a[3] fmt.Println(b) // 初始化方法2 c:[]int{6, 7, 8} //创建一个数组并返回⼀个切⽚ fmt.Println(c)}数组切片的基本操作a. arr[start:end]:包括start到end-1(包括end-1)之间的所有元素b. arr[start:]:包括start到arr最后⼀个元素(包括最后一个元素)之间的所有元素c. arr[:end]:包括0到end-1(包括end-1)之间的所有元素d. arr[:]:包括整个数组的所有元素切⽚修改package mainimport (fmt)func main() { //创建⼀个数组其中[...]是编译器确定数组的长度,darr的长度是9 darr:[...]int{57, 89, 90, 82, 100, 78, 67, 69, 59} //基于darr创建⼀个切⽚dslice,包括darr[2],darr[3],darr[4]三个元素 dslice:darr[2:5] fmt.Println(array before,darr) for i:range dslice { //对于dslice中每个元素进行1其实修改是darr[2],darr[3],darr[4] dslice[i] } fmt.Println(array after,darr)} // array before [57 89 90 82 100 78 67 69 59]// array after [57 89 91 83 101 78 67 69 59]切片是数组的引用当两个切片源于一个数组改变其中一个数组另一个数组也响应的进行的修改。package mainimport (fmt)func main() { numa:[3]int{78, 79 ,80} //创建⼀个切⽚包含整个数组的所有元素 nums1 : numa[:] nums2 : numa[:] fmt.Println(array before change 1,numa) nums1[0] 100 fmt.Println(array after modification to slice nums1, numa) nums2[1]101 fmt.Println(array after modification to slice nums2, numa)} // array before change 1 [78 79 80]// array after modification to slice nums1 [100 79 80]// array after modification to slice nums2 [100 101 80]使⽤make创建切片make为内建类型slice、map和channel分配内存。 package mainimport (fmt ) func main() { //[]中没有⻓度 第一个5 是切片的长度第二个 5是切片的容量 i:make([]int, 5, 5) fmt.Println(i) } // [0 0 0 0 0]切片的⻓度和容量 package mainimport (fmt ) func main() { var a []int a make([]int, 5, 10) a[0] 10 fmt.Printf(a%v addr:%p len:%d cap:%d\n, a,a,len(a),cap(a)) // a[10 0 0 0 0] addr:0xc0000a0000 len:5 cap:10 a append(a,11) fmt.Printf(a%v addr:%p len:%d cap:%d\n, a,a,len(a),cap(a)) //a[10 0 0 0 0 11] addr:0xc00009e000 len:6 cap:10 for i:0; i 8;i { a append(a, i) fmt.Printf(a%v addr:%p len:%d cap:%d\n, a,a,len(a),cap(a)) // a[10 0 0 0 0 11 0] addr:0xc00009e000 len:7 cap:10 // a[10 0 0 0 0 11 0 1] addr:0xc00009e000 len:8 cap:10 // a[10 0 0 0 0 11 0 1 2] addr:0xc00009e000 len:9 cap:10 // a[10 0 0 0 0 11 0 1 2 3] addr:0xc00009e000 len:10 cap:10 // a[10 0 0 0 0 11 0 1 2 3 4] addr:0xc0000a4000 len:11 cap:20 // a[10 0 0 0 0 11 0 1 2 3 4 5] addr:0xc0000a4000 len:12 cap:20 // a[10 0 0 0 0 11 0 1 2 3 4 5 6] addr:0xc0000a4000 len:13 cap:20 // a[10 0 0 0 0 11 0 1 2 3 4 5 6 7] addr:0xc0000a4000 len:14 cap:20 } // 观察切片的扩容操作 扩容的策略是翻倍扩容 a append(a,1000) fmt.Printf(a%v addr:%p len:%d cap:%d\n, a,a,len(a),cap(a)) // a[10 0 0 0 0 11 0 1 2 3 4 5 6 7 1000] addr:0xc0000200a0 len:15 cap:20 }例子2package mainimport (fmt)func main() { fruitarray :[...]string{ apple, orange, grape, mango, water melon, pine apple, chikoo} fruitslice:fruitarray[1:3]//长度是2容量is 6 fmt.Printf(length of slice %d capacity %d,len(fruitslice), cap(fruitslice))} // length of slice 2 capacity 6切片再切片package mainimport (fmt)func main() { fruitarray:[...]string{ apple, orange, grape, mango, water melon, pine apple, chikoo} fruitslice:fruitarray[1:3] //长度是2, 容量是6 fmt.Printf(length of slice %d capacity %d\n,len(fruitslice), cap(fruitslice)) //再重新进行切⽚不能⼤于数组fruitarray的⻓度否则越界 fruitslice fruitslice[:cap(fruitslice)] fmt.Println(After re-slicing length is,len(fruitslice), and capacity is,cap(fruitslice)) }// length of slice 2 capacity 6// After re-slicing length is 6 and capacity is 6append 操作package mainimport (fmt)func main() { cars:[]string{Ferrari, Honda, Ford} //⻓度和容量都等于3 fmt.Println(cars:, cars, has old length,len(cars), and capacity, cap(cars)) carsappend(cars, Toyota) //容量等于6 fmt.Println(cars:, cars, has new length,len(cars), and capacity, cap(cars))}// cars: [Ferrari Honda Ford] has old length 3 and capacity 3// cars: [Ferrari Honda Ford Toyota] has new length 4 and capacity 6a. append⼀个切⽚package mainimport (fmt)func main() { veggies:[]string{potatoes,tomatoes,brinjal} fruits :[]string{oranges,apples} //fruits后⾯的3个点表示展开fruits切⽚成⼀个元素 food: append( veggies, fruits...) fmt.Println(food:,food)}// food: [potatoes tomatoes brinjal oranges apples]空切片package mainimport (fmt ) func main() { //定义names是⼀个空切⽚⻓度和容量都等于0 //不能对空切⽚进行访问否则panic var names []string if names nil { fmt.Println(slice is nil going to append) names append(names, John, Sebastian, Vinay) fmt.Println(names contents:,names) }}切片传参package mainimport (fmt)//在函数内部修改numbers切⽚的值func subtactOne(numbers []int) { for i: range numbers { numbers[i]-2 }}func main() { nos:[]int{8, 7, 6} fmt.Println(slice before function call, nos) subtactOne(nos) //nos修改⽣效了说明切片是引⽤类型 fmt.Println(slice after function call, nos)}// slice before function call [8 7 6]// slice after function call [6 5 4]切片深拷贝package mainimport (fmt)func main() { // 当元素数量超过容量 // 切片会在底层申请新的数组 slice : make([]int, 5, 5) slice1 : slice slice append(slice, 1) slice[0] 1 fmt.Println(slice)//[1 0 0 0 0 1] fmt.Println(slice1)//[0 0 0 0 0] // copy 函数提供深拷贝功能 // 但需要在拷贝前申请空间 slice2 : make([]int, 4, 4) slice3 : make([]int, 5, 5) fmt.Println(copy(slice2, slice))//4 fmt.Println(copy(slice3, slice))//5 fmt.Println(slice2)// [1 0 0 0] fmt.Println(slice3)// [1 0 0 0 0] slice2[1] 2 slice3[1] 3 fmt.Println(slice)//[1 0 0 0 0 1] fmt.Println(slice2)//[1 2 0 0] fmt.Println(slice3)//[1 3 0 0 0]}切片遍历var a [3]inta[0] 10a[1] 20a[2] 30B : a[:]for index, val : range b {}//和数组遍历是⼀样的new⽤于各种类型的内存分配new返回是⼀个指针Go 变量和内存地址每个变量都有内存地址可以说通过变量来操作对应⼤大⼩小的内存 。注意:通过符号可以获取变量的地址。普通变量存储的是对应类型的值这些类型就叫值类型 例: var a int32。指针类型的变量存储的是一个地址所以⼜叫指针类型或引用类型, 在定义时前方加*就变为引用类型var a *int32, a中存储的是一个地址我们称为引用类型或者指针类型。package mainimport (fmt)func main() { var a int32 a 100 fmt.Printf(%d\n, a) fmt.Printf(%p\n, a) b:255 var c *int b fmt.Printf(Type of c is %T\n, c) fmt.Println(address of b is, c)}// 100// 0xc00001608c// Type of a is *int// address of b is 0xc00009a008指针类型变量的默认值为nil也就是空地址package mainimport (fmt)func main() { a : 25 var b *int if b nil { fmt.Println(b is, b) b a fmt.Println(b after initialization is, b) }}// b is // b after initialization is 0xc0000a2008如果操作指针变量指向的地址里面的值呢?注意:通过* 符号可以获取指针变量指向的变量。package mainimport (fmt)func main() { b : 255 a : b fmt.Println(address of b is, a) fmt.Println(value of b is,*a)}// address of b is 0xc00009a008// value of b is 255通过指针修改变量的值package mainimport (fmt)func main() { b : 255 a : b fmt.Println(address of b is, a) fmt.Println(value of b is, *a) *a fmt.Println(new value of b is,b)}// address of b is 0xc00009a008// value of b is 255// new value of b is 256指针变量传参package mainimport (fmt) func change (val *int){ *val 55}func main() { a : 255 fmt.Println(value of a before function call is,a) b : a change(b) fmt.Println(value of a after function call is, a)}// value of a before function call is 255// value of a after function call is 55// 例子2func change (arr *[3]int){ (*arr)[0] 90}func main() { a:[3]int{89, 90, 91} change(a) fmt.Println(a)}// [90 90 91]对比 切片传参注意:切片是引用类型!!func change (arr []int){ arr[0] 90}func main() { a:[3]int{89, 90, 91} change(a[:]) fmt.Println(a)}// [90 90 91]// make⽤来分配引⽤类型的内存⽐如 map、slice以及channel ,new⽤来分配除引用类型的所有其他类型的内存⽐如 int、数组等 值拷⻉和引⽤拷⻉ package mainimport (fmt ) func main() { // 值拷贝 var a int 100 b : a // 引用拷贝 var a int 100 var b *int a var c *int b *c 200 }Go Map 类型map类型是⼀个key-value的数据结构。注意:map必须初始化才能使⽤否则panic。map类型的变量默认初始化为nil需要使用make分配map内存。//var a map[key的类型]value类型 var a map[string]intvar b map[int]stringvar c map[float32]stringpackage mainimport (fmt) func main() { var a map[string]int if a nil { fmt.Println(map is nil. Going to make one.) a make(map[string]int) }}map插入操作package mainimport (fmt) func main() { a : make(map[string]int) a[steve] 12000 a[jamie] 15000 a[mike] 9000 fmt.Println(a map contents:, a)}// a map contents: map[jamie:15000 mike:9000 steve:12000]map 声明方式二, 通过key访问map中的元素package mainimport (fmt) func main() { a : map[string]int { steve: 12000, jamie: 15000, } a[mike] 9000 fmt.Println(a map contents:, a)}如何判断map指定的key是否存在? value, ok : map[key]package mainimport (fmt) func main() { a : map[string]int { steve: 12000, jamie: 15000, } a[mike] 9000 b : joe value, ok : a[b] if ok true { fmt.Println(Salary of, b, is, value) } else { fmt.Println(b,not found) } fmt.Println(a map contents:, a)}// joe not found// a map contents: map[jamie:15000 mike:9000 steve:12000]map遍历操作package mainimport (fmt) func main() { a : map[string]int { steve: 12000, jamie: 15000, } a[mike] 9000 for key, value: range a { fmt.Printf(personSalary[%s] %d\n, key, value) }}// personSalary[steve] 12000// personSalary[jamie] 15000// personSalary[mike] 9000map删除元素package mainimport (fmt) func main() { a : map[string]int { steve: 12000, jamie: 15000, } a[mike] 9000 delete(a, steve) fmt.Println(map after deletion, a)}// map after deletion map[jamie:15000 mike:9000]map的⻓度 len(a)package mainimport (fmt) func main() { a : map[string]int { steve: 12000, jamie: 15000, } a[mike] 9000 fmt.Println(length is, len(a))}// length is 3map是引⽤类型package mainimport (fmt) func main() { a : map[string]int { steve: 12000, jamie: 15000, } a[mike] 9000 b : a b[mike] 18000 fmt.Println(a map changed, a)}// a map changed map[jamie:15000 mike:18000 steve:12000]默认情况下map并不是按照key有序进⾏遍历的 ,map按照key进行排序遍历 。package mainimport (fmtsort)func main() { var a map[string]int make(map[string]int, 10) for i : 0; i 10; i { key : fmt.Sprintf(key%d, i) a[key] i } var keys []string for key, _ : range a { keys append(keys, key) } sort.Strings(keys) for _, key : range keys { fmt.Printf(key:%s%d\n, key, a[key]) }} // key:key00// key:key11// key:key22// key:key33// key:key44// key:key55// key:key66// key:key77// key:key88// key:key99map类型的切⽚ package mainimport (fmt ) func main() { var mapSlice []map[string]int mapSlice make([]map[string]int, 5) fmt.Println(before map init) for index, value : range mapSlice { fmt.Printf(index:%d value:%v\n, index, value) } mapSlice[0] make(map[string]int, 10) mapSlice[0][a] 1000 mapSlice[0][b] 2000 mapSlice[0][c] 3000 mapSlice[0][d] 4000 mapSlice[0][e] 5000 fmt.Println(after map init) for index, value : range mapSlice { fmt.Printf(index:%d value:%v\n, index, value) } } // before map init// index:0 value:map[]// index:1 value:map[]// index:2 value:map[]// index:3 value:map[]// index:4 value:map[]// after map init// index:0 value:map[a:1000 b:2000 c:3000 d:4000 e:5000]// index:1 value:map[]// index:2 value:map[]// index:3 value:map[]// index:4 value:map[]Go 面向对象编程struct声明和定义Go中⾯向对象是通过struct来实现的, struct是用户⾃定义的类型 , 注意:type是⽤来定义⼀种类型 type User struct { Username string Sex string Age int AvatarUrl string }初始化 方法分为两种:方法一:注意:使⽤变量名 ‘.’ 字段名访问结构体中的字段var user Useruser.Age 18user.Username “user01”user.Sex “男”user.AvatarUrl “http://my.com/xxx.jpg方法二:var user User User { “Username” : “user01”, “Age”: 18, “Sex”: “男”, “AvatarUrl”: “http://my.com/xxx.jpg”,}更简单的写法: user : User { “Username” : “user01”, “Age”: 18, “Sex”: “男”, “AvatarUrl”: “http://my.com/xxx.jpg”,}struct初始化的默认值是什么? var user User fmt.Printf(“%#v\n”, user)结构体类型的指针注意:User{}和new(User) 本质上是⼀样的都是返回一个 结构体的地址package mainimport (fmt) func main() { var user *User User{} fmt.Printf(“%p %#v\n”, user) // 直接初始化: var user *User User { Username : “user01”, Age: 18, Sex: “男”, AvatarUrl: “http://my.com/xxx.jpg”, } // 或者使用new var user User new(User) user.Age 18 user.Username “user01” user.Sex “男” user.AvatarUrl “http://my.com/xxx.jpg }结构体的内存布局: 占⽤⼀段连续的内存空间结构体没有构造函数 必要时需要⾃⼰实现匿名字段: 即没有名字的字段 注意:匿名字段默认采用类型名作为 字段名 type User struct { Username string Sex string Age int AvatarUrl string } type User struct { Username string Sex string Age int AvatarUrl string int string}结构体嵌套type Address struct { City string Province string }type User struct { Username string Sex string Age int AvatarUrl string address *Address} func main () { user : User { Username: user01, Sex: man, address: Address { Province: beijing, City: beijing, }, }}匿名结构体第二种方式 先在结构体里面找Provice以及City,如果结构体里面没有则在匿名结构体里面找type Address struct { City string Province string}type User struct { Username string Sex string Age int AvatarUrl string *Address}func main () { var user User user.Username user01 user.Sex man // 第一种方式 user.Address Address{ Provice: bj, City: bj } // 第二种方式 user.Province bj01 user.City bj01}匿名结构体的冲突解决 使用结构体的字段如果结构体字段有值则使用结构体如果没有则使用匿名结构体的字段 如果两个匿名结构体都有相同的字段当访问这个相同字段时候要指定访问那个匿名结构体的字段package mainimport (fmt)type Address struct { City string Province string CreateTime string}type Email struct { Account string CreateTime string}type User struct { Username string Sex string Age int AvatarUrl string *Address *Email CreateTime string}func main (){ var user User user.Username user01 user.Sex man user.City bj user.Address new(Address) user.Email new(Email) user.Address.City bj01 user.Address.CreateTime 001 user.Email.CreateTime 002 fmt.Println( user.Email.CreateTime, user.Address.CreateTime)} 字段可⻅性⼤写表示可公开访问⼩写表示私有type User struct { Username string Sex string Age int avatarUrl string // 私有 CreateTime string}tag是结构体的元信息可以在运行的时候通过反射的机制读取出来 字段类型后⾯以反引号括起来的 key-value结构的字符串多个tag 以逗号隔开。type User struct { Username string json:”username”,db:”user_name” Sex string json:”sex” Age int json:”age” avatarUrl string CreateTime string}Go 方法的定义和其他语⾔不⼀样Go的⽅法采⽤另外⼀种⽅式实现Go的⽅法是在函数前⾯加上一个接受者这样编译器就知道这个⽅法属于哪个类型了可以为当前包内定义的任何类型增加方法函数和方法的区别: 函数不属于任何类型⽅法属于特定的类型指针类型作为接受者指针类型和值类型作为接受者的区别值类型:type People struct { Name string Country string}func (p People) Print() { fmt.Println(name%s country%s\n,p.Name, p.Country)}func (p People) Set(name string, country string) { p.Name name p.Country country}func main() { var p1 People People { Name: people01, Country: china, } p1.Print() // people01 china p1.Set(people02,english) p1.Print() // 不变 p是实例的拷贝 people01 china} 指针类型:type People struct { Name string Country string}func (p People) Print() { fmt.Println(name%s country%s\n,p.Name, p.Country)}// 值类型func (p People) Set(name string, country string) { p.Name name p.Country country}// 引用类型func (p *People) SetV2(name string, country string) { p.Name name p.Country country }func main() { var p1 People People { Name: people01, Country: china, } p1.Print() // people01 china p1.Set(people02,english) p1.Print() // 不变 p是实例的拷贝 people01 china (p1).SetV2(people02,english)或 语法糖: p1.SetV2(people02,english) p1.Print() // 变了 people02 english} 什么时候用值类型/指针类型作为接受者?a. 需要修改接受者中的值的时候 b. 接受者是⼤对象的时候副本拷贝代价⽐较大 c. ⼀般来说通常使⽤指针类型作为接受者匿名结构体与继承通过组合 和 匿名字段实现的继承方法的冲突解决和匿名字段的冲突解决一致都是通过指定对应的实例的方法解决type Anaimal struct { Name string Sex string}func (a *Anaimal) Talk() { fmt.Println(a.Name)}type Dog struct { Feet string *Anaimal}func (d *Dog) Eat () { fmt.Println(dog is eat)}func main () { var d *Dog Dog{ Feet: Four Feet, Anaimal: Anaimal { Name: dog, Sex: xiong, }, } d.Name dog d.Sex xiong d.Eat() d.Talk()}多重继承与冲突解决type Mother struct { Name string } type Father struct { Name string } type People struct { Sex string Age int *Mother *Father }结构体与json序列列化package mainimport (encoding/jsonfmt)type Student struct { Id string Name string Sex string}type Class struct { Name string Count int Students []*Student}var rawJson {Name:101,Count:0,Students:[{Id:0,Name:stu0,Sex:man},{Id:1,Name:stu1,Sex:man},{Id:2,Name:stu2,Sex:man},{Id:3,Name:stu3,Sex:man},{Id:4,Name:stu4,Sex:man},{Id:5,Name:stu5,Sex:man},{Id:6,Name:stu6,Sex:man},{Id:7,Name:stu7,Sex:man},{Id:8,Name:stu8,Sex:man},{Id:9,Name:stu9,Sex:man}]}func main() { c : Class{ Name: 101, Count: 0, } for i : 0; i 10; i { stu : Student{ Name: fmt.Sprintf(stu%d, i), Sex: man, Id: fmt.Sprintf(%d, i), } c.Students append(c.Students, stu) } data, err : json.Marshal(c) if err ! nil { fmt.Println(json marshal failed) return } fmt.Printf(json:%s\n, string(data)) //json反序列化 fmt.Println(unmarshal result is \n\n) var c1 *Class Class{} err json.Unmarshal([]byte(rawJson), c1) if err ! nil { fmt.Println(unmarhsal failed) return } fmt.Printf(c1:%#v\n, c1) for _, v : range c1.Students { fmt.Printf(stu:%#v\n, v) }}推荐阅读(点击标题可跳转阅读)RxJS入门一文掌握Webpack编译流程一文深度剖析Axios源码Javascript条件逻辑设计重构Promise知识点自测你不知道的React Diff你不知道的GIT神操作程序中代码坏味道(上)程序中代码坏味道(下)学习Less,看这篇就够了一文掌握GO语言实战技能(一)一文掌握Linux实战技能-系统管理篇一文掌握Linux实战技能-系统操作篇一文达到Mysql实战水平一文达到Mysql实战水平-习题答案从表单抽象到表单中台vue源码分析(1)- new Vue实战LeetCode 系列(一) (题目解析)一文掌握Javascript函数式编程重点实战LeetCode - 前端面试必备二叉树算法一文读懂 React16.0-16.6 新特性(实践 思考)阿里、网易、滴滴、今日头条、有赞.....等20家面试真题30分钟学会 snabbdom 源码实现精简的 Virtual DOM 库觉得本文对你有帮助请分享给更多人关注「React中文社区」加星标每天进步