代码简单演示:
package main
import "fmt"
//main方法调用前会被调用
func init() {
fmt.Println("init方法会在main方法调用前会被调用")
}
//声明全局变量 方法一,二,三是可以的,但是方法四不行
var g1 int
var g2 int =520
var g3 =521
//方法四声明全局变量会报错
//:=只能用在函数体内使用
//g4:=1000
func main() {
fmt.Println("=============================")
fmt.Println("方法一:声明一个变量,默认值为0")
var a int
//Println是换行输出
fmt.Println("a= ", a)
//Printf是格式化输出--需要手动换行
fmt.Printf("type of a= %T \n", a)
fmt.Println("=============================")
fmt.Println("方法二: 声明一个变量,初始化一个值")
var b int = 100
fmt.Println("b= ", b)
fmt.Printf("type of b= %T \n", b)
fmt.Println("=============================")
fmt.Println("方法二: 声明一个变量,初始化一个值")
var s string = "大忽悠";
fmt.Printf("type of s= %T\n", s)
fmt.Println("=============================")
fmt.Println("方法三:在初始化的时候,省略数据类型,通过值自动匹配当前的变量的数据类型")
var c = 100
fmt.Println("c= ", c)
fmt.Printf("type of c= %T \n", c)
fmt.Println("=============================")
fmt.Println("方法四: 省去var关键字,直接自动匹配")
e := "哈哈哈哈"
fmt.Println("e =",e)
fmt.Printf("type of e= %T\n",e)
fmt.Println("=============================")
fmt.Println("方法四: 省去var关键字,直接自动匹配")
f := 3.14
fmt.Println("f =",f)
fmt.Printf("type of f= %T\n",f)
fmt.Println("=============================")
fmt.Println("全局变量输出测试: g1=",g1," g2=",g2," g3=",g3)
fmt.Println("=============================")
//声明多个变量
var xx,yy int =100,200
fmt.Println("同时声明多个类型相同的变量: xx=",xx," yy=",yy)
var kk,ll=300,"呜呜呜"
fmt.Println("同时声明多个类型不同的变量: kk=",kk," ll=",ll)
fmt.Println("=============================")
fmt.Println("多行的变量声明测试: ")
var (
aa int =100
bb bool=true
)
fmt.Println("aa= ",aa," bb=",bb)
}
输出结果:
init方法会在main方法调用前会被调用
=============================
方法一:声明一个变量,默认值为0
a= 0
type of a= int
=============================
方法二: 声明一个变量,初始化一个值
b= 100
type of b= int
=============================
方法二: 声明一个变量,初始化一个值
type of s= string
=============================
方法三:在初始化的时候,省略数据类型,通过值自动匹配当前的变量的数据类型
c= 100
type of c= int
=============================
方法四: 省去var关键字,直接自动匹配
e = 哈哈哈哈
type of e= string
=============================
方法四: 省去var关键字,直接自动匹配
f = 3.14
type of f= float64
=============================
全局变量输出测试: g1= 0 g2= 520 g3= 521
=============================
同时声明多个类型相同的变量: xx= 100 yy= 200
同时声明多个类型不同的变量: kk= 300 ll= 呜呜呜
=============================
多行的变量声明测试:
aa= 100 bb= true
package main
import "fmt"
//const定义枚举类型
const(
SUCCESS=200
NOT_FOUND=404
ERROR=500
)
const(
//可以在const()添加一个关键字iota,每行的iota都会增加1,第一行的iota默认为0
ZERO=iota //iota=0
FIRST //iota=1
SECOND //iota=2
THREE //iota=3
)
const (
a,b =iota+1,iota+2 //iota=0,a=iota+1,b=iota+2,a=1,b=2
c,d //iota=1,c=iota+1,d=iota+2,c=2,d=3
e,f //iota=2,e=iota+1,f=iota+2,e=3,f=4
g,h =iota*2,iota*3 //iota=3,g=iota*2,h=iota*3,g=6,h=9
i,k //iota=4,i=iota*2,k=iota*3 ,i=8,k=12
)
func main() {
//常量---只读
const len int =10;
fmt.Println("len= ",len)
fmt.Println("SUCCESS: ",SUCCESS)
fmt.Println("NOT_FOUND: ",NOT_FOUND)
fmt.Println("ERROR: ",ERROR)
fmt.Println("a= ",a," b= ",b)
fmt.Println("c= ",c," d= ",d)
fmt.Println("e= ",e," f= ",f)
fmt.Println("g= ",g," h= ",h)
fmt.Println("i= ",i," k= ",k)
//iota只能够配合const()一起使用,iota在const()才有累加效果
//var temp int=iota;
}
package main
import "fmt"
//函数返回一个值
func foo1(a string,b int) int{
fmt.Println("a= ",a)
fmt.Println("b= ",b)
c:=100
return c
}
//返回多个值,匿名的
func fool2(a string)(int,int){
fmt.Println("a= ",a)
return 666,777
}
//返回多个值,有形参名称的
func fool3(a string)(r1 string, r2 int){
fmt.Println("a= ",a)
//给有名称的返回值变量赋值
r1="大忽悠"
r2=100
return
}
func fool4(a string)(r1,r2 int){
fmt.Println("a= ",a)
//对于形参a和返回值变量r1,r2来说,他们的生命周期被局限在当前方法体内
//但是对于返回值变量r1和r2来说,如果不进行赋值,默认为0
fmt.Println("r1= ",r1," r2= ",r2)
//给有名称的返回值变量赋值
r1=520
r2=100
return
}
func main() {
fmt.Println("foo1函数返回一个值: ",foo1("大 fu you",100))
fmt.Println("----------------------------------------------")
ret1,ret2:=fool2("哈哈哈2")
fmt.Println("fool2函数有多个返回值,ret1= ",ret1," ret2= ",ret2)
fmt.Println("----------------------------------------------")
ret3,ret4:=fool3("哈哈哈3")
fmt.Println("fool3函数有多个返回值,ret3= ",ret3," ret4= ",ret4)
fmt.Println("----------------------------------------------")
ret5,ret6:=fool4("哈哈哈4")
fmt.Println("fool4函数有多个返回值,ret5= ",ret5," ret6= ",ret6)
fmt.Println("----------------------------------------------")
}
导包测试:
package handle
import "fmt"
func init() {
fmt.Println("afterHandle执行初始化逻辑")
}
func AfterHandle(){
fmt.Println("方法执行后的拦截逻辑.....")
}
package handle
import "fmt"
func init() {
fmt.Println("beforeHandle执行初始化逻辑")
}
func BeforeHandle() {
fmt.Println("方法执行前的拦截逻辑.....")
}
导入handle包:
package main
import (
"fmt"
"handle"
)
func main() {
handle.BeforeHandle()
fmt.Println("哈哈哈哈")
handle.AfterHandle()
}
结果:
package handle
import "fmt"
func init() {
fmt.Println("beforeHandle执行初始化逻辑")
}
//当前函数名大写,表示当前函数对外开放,别的包只要导入了该包,便可以调用这个函数
//如果当前函数名小写,表示当前函数只能在当前包内被调用
func BeforeHandle() {
fmt.Println("方法执行前的拦截逻辑.....")
}
匿名导入:
package main
import (
"fmt"
_"handle"
)
func main() {
fmt.Println("哈哈哈哈")
}
别名导入:
package main
import (
"fmt"
myhandle "handle"
)
func main() {
myhandle.BeforeHandle()
fmt.Println("哈哈哈哈")
myhandle.AfterHandle()
}
全部导入本包: 这种方法在多个包的情况下容易产生方法名冲突的问题
package main
import (
"fmt"
. "handle"
)
func main() {
BeforeHandle()
fmt.Println("哈哈哈哈")
AfterHandle()
}
defer关键字的功能类似于c++的析构函数,用defer关键字声明的函数,会在当前方法执行结束后被执行,并且执行顺序类似于栈的先进后出关系
先声明的方法defer方法先入栈,因此后执行
package main
import "fmt"
func func1() {
fmt.Println("A")
}
func func2() {
fmt.Println("B")
}
func func3() {
fmt.Println("C")
}
func main(){
defer func1()
fmt.Println("hhh")
defer func2()
defer func3()
}
当defer和return同时出现,return先执行,defer后执行
package main
import "fmt"
func func1() {
fmt.Println("A")
}
func func2() int{
fmt.Println("B")
return 0;
}
func func3() int {
fmt.Println("C")
defer func1()
return func2();
}
func main(){
func3()
}
package main
import "fmt"
//只能接受长度为8的固定数组
//在go语言中,所有的变量都是值传递
func printArr(arr [8]int){
arr[0]=520
fmt.Println("函数中输出传入后修改的数组: ")
for index, val := range arr {
fmt.Println("index: ",index," val: ",val)
}
}
func main() {
//固定长度的数组
var arr1 [10]int;
fmt.Println("打印输出arr1数组: ");
for i:=0; i<len(arr1) ;i++ {
fmt.Print(arr1[i]," ")
}
fmt.Println()
fmt.Println("--------------------------------------------")
arr2:=[8]int{1,2,3,4,5}
//下面arr2的输出,也可以验证这里是数组值传递
printArr(arr2)
for index, val := range arr2 {
fmt.Println("当前遍历索引为: ",index," 当前索引对应的值为: ",val)
}
fmt.Println("查看数组的类型:")
fmt.Printf("arr1数组的类型为: %T\n",arr1)
fmt.Printf("arr2数组的类型为: %T\n",arr2)
}
//这里拿到的是数组的指针
func printArr(arr []int){
arr[0]=520
fmt.Println("函数中输出传入后修改的数组: ")
for index, val := range arr {
fmt.Println("index: ",index," val: ",val)
}
}
func main() {
//动态数组---切片---slice
arr2:=[]int{1,2,3,4,5}
//动态数组就是执行这块数组内存的一个指针引用
//因此这里函数传递的是指向这块内存的一个指针引用
printArr(arr2)
for index, val := range arr2 {
fmt.Println("当前遍历索引为: ",index," 当前索引对应的值为: ",val)
}
}
动态数组在传参上是引⽤传递,⽽且不同元素⻓度的动态数组他们的形参是⼀致。
package main
import "fmt"
func main() {
fmt.Println("声明slcie1是一个切片,并且初始化,默认值为1,2,3 长度为3: ")
slice1 := []int{1,2,3}
fmt.Println(slice1)
fmt.Println("----------------------------")
fmt.Println("声明slice2是一个切片,但是并没有给slice分配空间")
var slice2 []int;
fmt.Println(slice2)
fmt.Println("----------------------------")
fmt.Println("给slice2开辟三个空间,默认值为0: ")
slice2=make([]int,3)
fmt.Println(slice2)
fmt.Println("----------------------------")
fmt.Println("声明slice3是一个切片,同时给slice3分配三个空间,默认值为0")
var slice3 []int=make([]int,3);
fmt.Println(slice3)
fmt.Println("----------------------------")
fmt.Println("声明slice4是一个切片,同时给slice4分配空间,3个空间,通过:=推导出slice4是一个切片")
slice4:=make([]int,3)
slice4[0]=1
slice4[1]=2
slice4[2]=3
fmt.Println(slice4)
fmt.Println("----------------------------")
fmt.Println("输出slice4切片的长度和详细信息(-v): ")
fmt.Printf("len= %d,slice= %v\n",len(slice4),slice4)
fmt.Println("----------------------------")
fmt.Println("判断一个slice是否为0")
if slice3 == nil{
fmt.Println("slice3是一个空切片")
}else {
fmt.Println("slice3是有空间的")
}
var slice5 []int;
if slice5 == nil{
fmt.Println("slice5是一个空切片")
}else {
fmt.Println("slice5是有空间的")
}
}
package main
import "fmt"
func main() {
//最后一个参数指定的是切片容量
var nums=make([]int,3,5)
fmt.Printf("切片长度= %d, 切片容量为= %d, 切片详细信息=%v \n",len(nums),cap(nums),nums)
}
len和cap有啥区别呢?—>看图
func main() {
//最后一个参数指定的是切片容量
var nums=make([]int,3,5)
info(nums)
fmt.Println("向nums切片追加一个元素1")
nums=append(nums,1,2)
info(nums)
}
func info(nums []int){
fmt.Printf("切片长度= %d, 切片容量为= %d, 切片详细信息=%v \n",len(nums),cap(nums),nums)
}
如果此时在追加一条数据呢?
显然会扩容,每次扩容为当前cap两倍的大小
package main
import "fmt"
func main() {
//创建切片
nums:=[]int{1,2,3,4,5,6,7}
info(nums)
//切片截取---联想JAVA中String的subString功能
info(nums[1:4])
//默认下限为0
info(nums[:3])
//模式上限为len(s)
info(nums[4:])
}
func info(nums []int){
fmt.Printf("切片长度= %d, 切片容量为= %d, 切片详细信息=%v \n",len(nums),cap(nums),nums)
}
截取只是利用指针实现了逻辑上的分离,物理上还是一块内存,因此对截取后某部分的数据进行操作,会影响原切片
package main
import "fmt"
func main() {
//创建切片
nums:=[]int{1,2,3,4,5,6,7}
info(nums)
nums1:=nums[1:4]
nums1[0]=520
info(nums)
info(nums1)
}
func info(nums []int){
fmt.Printf("切片长度= %d, 切片容量为= %d, 切片详细信息=%v \n",len(nums),cap(nums),nums)
}
package main
import "fmt"
func main() {
//创建切片
nums:=[]int{1,2,3,4,5,6,7}
info(nums)
s2:=make([]int,3)
copy(s2,nums)
info(s2)
s2[0]=520
info(nums)
info(s2)
}
func info(nums []int){
fmt.Printf("切片长度= %d, 切片容量为= %d, 切片详细信息=%v \n",len(nums),cap(nums),nums)
}
可以看出copy函数是深拷贝的实现
package main
import (
"fmt"
)
func main() {
//声明一个map类型,key是String,val是String
var myMap1 map[string]string
if myMap1==nil{
fmt.Println("myMap1是一个空map")
}
//在使用map前,需要先用make给map分配数据空间
myMap1=make(map[string]string,10)
myMap1["one"]="java"
myMap1["two"]="c++"
myMap1["three"]="python"
fmt.Println(myMap1)
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
//第二种声明方式
myMap2:=make(map[int]string);
myMap2[0]="123"
myMap2[1]="321"
fmt.Println(myMap2)
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
//第三种声明方式
myMap3:=map[int]string{
1 :"dhy",
2 :"ddhy",
}
fmt.Println(myMap3)
}
package main
import "fmt"
//这里传递的是map的引用
func printMap(map1 map[string]string){
//遍历元素
for key, val := range map1 {
fmt.Print(" key= ",key)
fmt.Print(" val= ",val)
fmt.Println()
}
fmt.Println("-------------------")
}
func main() {
map1:=make(map[string]string)
//添加元素
map1["China"]="BeiJing"
map1["Japan"]="Tokyo"
map1["USA"]="NewYork"
printMap(map1)
//删除元素
delete(map1,"China")
printMap(map1)
//修改元素
map1["USA"]="DC"
printMap(map1)
}
package main
import "fmt"
//声明一种行的数据类型myint,是int的一个别名
type myint int
//定义一个结构体
type Book struct {
title string
auth string
}
//值传递
func changeBook(book Book){
book.auth="大忽悠";
}
//地址传递
func changeBook1(book *Book){
book.auth="大忽悠";
}
func main() {
var tempVal myint=100
fmt.Println("tempVal=",tempVal)
fmt.Println("--------------------")
var book Book
book.title="Go语言圣经"
book.auth="不知道"
fmt.Printf("%v\n",book)
fmt.Println("--------------------")
//值传递
changeBook(book)
fmt.Printf("%v\n",book)
fmt.Println("--------------------")
//地址传递
changeBook1(&book)
fmt.Printf("%v\n",book)
fmt.Println("--------------------")
}
package main
import "fmt"
//声明一种行的数据类型myint,是int的一个别名
type myint int
//定义一个结构体
//类名首字母大写,表示该属性对外可以访问,否则只能当前包类访问
type Book struct {
title string
auth string
}
//这里方法名首字母大小写同上
func (this Book) getTitle() string{
return this.title
}
//值传递---this Book
func (this Book) setTitle(title string){
//这里调用该方法对象的一个副本---拷贝
this.title=title
}
//引用传递
func (this *Book) setTitle1(title string){
this.title=title
}
func (this Book) show() {
fmt.Println("书名: ",this.title," 作者: ",this.auth)
}
func main() {
book:=Book{title:"大忽悠历险记",auth:"大忽悠"}
book.show()
fmt.Println("值传递演示: ")
book.setTitle("小朋友历险记")
book.show()
fmt.Println("引用传递演示: ")
book.setTitle1("小朋友历险记")
book.show()
}
类名、属性名、⽅法名 ⾸字⺟⼤写表示对外(其他包)可以访问,否则只能够在本包内访问
package main
import "fmt"
type Huamn struct {
name string
sex string
}
func (this *Huamn) Eat(){
fmt.Println("Huamn.Eat()...")
}
func (this *Huamn) Walk(){
fmt.Println("Huamn.Walk()...")
}
///
type SuperMan struct {
Huamn //SuperMan类继承了HUMAN类的方法和属性
level int
}
//重写了父类的方法
func (this *SuperMan) Eat(){
fmt.Println("SuperMan.Eat()...")
}
func (this *SuperMan) Play(){
fmt.Println("SuperMan.Play()...")
}
func (this SuperMan) Show(){
fmt.Println("姓名: ",this.name," 性别: ",this.sex," 等级: ",this.level)
}
func main() {
huamn:= Huamn{name: "大忽悠", sex: "未知"}
huamn.Eat()
huamn.Walk()
//定义一个子类对象
superMan:= SuperMan{Huamn{name: "小朋友", sex: "未知"}, 1000}
superMan.Show()
//方式二:
var s SuperMan
s.level=520
s.name="大忽悠"
s.sex="MAN"
s.Show()
}
Go语言对烦人的权限做了删减,继承过程中没有啥子私有,公开,保护权限,只在是否对其他包公开这里做了权限限制,而且这一点是通过大小写完成的
基本要素:
//本质是一个指针
type Animal interface {
Sleep()
GetColor() string
GetType() string
}
type Cat struct {
color string
}
func (this *Cat) Sleep(){
fmt.Println("Cat is Sleep")
}
func (this *Cat) GetColor() string{
return this.color
}
func (this *Cat) GetType() string{
return "Cat"
}
type Dog struct {
color string
}
func (this *Dog) Sleep(){
fmt.Println("Dog is Sleep")
}
func (this *Dog) GetColor() string{
return this.color
}
func (this *Dog) GetType() string{
return "Dog"
}
package main
import (
"fmt"
)
//本质是一个指针
type Animal interface {
Sleep()
GetColor() string
GetType() string
}
type Cat struct {
color string
}
func (this *Cat) Sleep(){
fmt.Println("Cat is Sleep")
}
func (this *Cat) GetColor() string{
return this.color
}
func (this *Cat) GetType() string{
return "Cat"
}
type Dog struct {
color string
}
func (this *Dog) Sleep(){
fmt.Println("Dog is Sleep")
}
func (this *Dog) GetColor() string{
return this.color
}
func (this *Dog) GetType() string{
return "Dog"
}
func test(animal Animal){
animal.Sleep()
color := animal.GetColor()
getType := animal.GetType()
fmt.Println("动物的颜色: ",color," 类型为: ",getType)
}
func main() {
//接口的数据类型,父类指针
var animal Animal
animal=&Cat{"BLACK"}
test(animal)
animal=&Dog{"BROWN"}
test(animal)
}
package main
import "fmt"
//interface{}是万能类型
func myFunc(arg interface{}){
fmt.Println("myFunc is called...")
fmt.Println(arg)
//interface{}该如何区分,此时引用的底层数据类型到底是什么
//给interface{}提供"类型断言"的机制
//返回的第二个参数是一个bool,表示当前断言的结果,第一个参数就是值
val, ok := arg.(Book1)
if !ok{
fmt.Println("arg is not Book1 type")
}else{
fmt.Println("arg is Book1 type,val= ",val)
fmt.Printf("value type is %T\n",val)
}
}
type Book1 struct {
auth string
}
func main() {
book := Book1{auth: "哈哈哈哈"}
myFunc(book)
}
这里空接口类型指针,可以指向任何数据类型,因此可以看做是元数据类型,即所有数据类型都会实现的类型。这里可以类比JAVA中的Object
package main
import "fmt"
func main() {
var a string
//pair<statictype:string , value: "abcd">
a="abcd"
//pair<type: value:>
var allType interface{}
//pair<concretetype:string , value: "abcd">
allType=a
//通过断言找到类型并打印对应的值
s,_ := allType.(string)
fmt.Println(s)
}
大家可以先理解一下
package main
import "fmt"
type Reader interface {
ReadBook()
}
type Writer interface {
WriterBook()
}
type Book2 struct {
}
func (this * Book2) ReadBook(){
fmt.Println("read book")
}
func (this * Book2) WriterBook(){
fmt.Println("writer book")
}
func main() {
//b: pair<type:Book value:book{}地址>
b:=&Book2{}
//r: pair<type: ,value: >
var r Reader
//r:pair<type:Book,value:book{}地址>
r=b
r.ReadBook()
var w Writer
//w: pair<type:Book,value:book{}地址>
//这里是断言,返回断言后的值---也可以看做是类型转换
//这里r和w具体的type是一致的
w=r.(Writer)
w.WriterBook()
}
例子1:
package main
import (
"fmt"
"reflect"
)
func reflectTest(arg interface{}){
fmt.Println("type: ",reflect.TypeOf(arg))
fmt.Println("value: ",reflect.ValueOf(arg))
}
func main() {
num:=1.23
reflectTest(num)
}
例子2:
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
Age int
}
func (this User) Show(){
fmt.Println("name= ",this.Name," age= ",this.Age)
}
func reflectTest(arg interface{}){
typeOf := reflect.TypeOf(arg)
valueOf := reflect.ValueOf(arg)
fmt.Println("type: ",typeOf)
fmt.Println("value: ",valueOf)
//通过type,获取里面的字段
//1.获取interface的reflectType,通过Type得到NumField,进行遍历
//2.得到每个Field,数据类型
//3.通过filed有一个interface()方法得到对应的value
for i:=0; i<typeOf.NumField();i++ {
//输出字段类型相关的信息
fieldType:=typeOf.Field(i)
fmt.Println("当前field字段名: ",fieldType.Name," 字段所在包: ",fieldType.PkgPath,
" 字段类型: ",fieldType.Type," 字段索引: ",fieldType.Index,
"字段是否匿名: ",fieldType.Anonymous," 字段偏移量: ",fieldType.Offset,
" 字段的标签: ",fieldType.Tag)
//输出字段值相关的信息
//go语言里面struct里面变量如果大写则是public,如果是小写则是private的,private的时候通过反射不能获取其值
fieldVal:=valueOf.Field(i).Interface()
fmt.Println("当前字段的值为: ",fieldVal)
fmt.Println("-----------------------------------------------------------")
}
//通过type获取里面的方法,调用
method := typeOf.NumMethod()
fmt.Println("方法数量: ",method)
for j:=0;j<typeOf.NumMethod() ;j++ {
m:=typeOf.Method(j)
fmt.Println("方法名: ",m.Name," 方法类型: ",m.Type)
fmt.Println("-----------------------------------------------------------")
}
}
func main() {
user := User{Name: "大忽悠", Age: 18}
reflectTest(user)
}
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string `info:"name"`
Age int `info:"age"`
}
func (this User) Show(){
fmt.Println("name= ",this.Name," age= ",this.Age)
}
func reflectTest(arg interface{}){
typeOf := reflect.TypeOf(arg)
for i:=0; i<typeOf.NumField();i++ {
//输出字段类型相关的信息
fieldType := typeOf.Field(i)
fmt.Println("当前field字段名: ", fieldType.Name, " 字段所在包: ", fieldType.PkgPath,
" 字段类型: ", fieldType.Type, " 字段索引: ", fieldType.Index,
"字段是否匿名: ", fieldType.Anonymous, " 字段偏移量: ", fieldType.Offset,
" 字段的标签: ", fieldType.Tag)
//获取标签里面某个属性的值
tag:= fieldType.Tag
info := tag.Get("info")
fmt.Println("标签中info对应的值为: ",info)
fmt.Println("---------------------------------------------------------")
}
}
func main() {
user := User{Name: "大忽悠", Age: 18}
reflectTest(user)
}
package main
import (
"encoding/json"
"fmt"
)
type Movie struct {
Title string `json:"title"`
Year int `json:"year"`
Price int `json:"rmb"`
Actors []string `json:"actors"`
}
func main() {
movie := Movie{Title: "大忽悠", Year: 2023, Price: 1000000, Actors: []string{"大忽悠", "小朋友"}}
//编码的过程: 将结构体转换为Json
jsonStr,err := json.Marshal(movie)
if err!=nil{
fmt.Println("json format error : ",err)
return
}
fmt.Printf("jsonStr = %s\n",jsonStr)
//解码的过程: jsonstr--->结构体
movie1 := Movie{}
err = json.Unmarshal(jsonStr, &movie1)
if err!=nil{
fmt.Println("json Unmarshal error : ",err)
return
}
fmt.Printf("movie1 %v\n",movie1)
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://cjdhy.blog.csdn.net/article/details/123854847
内容来源于网络,如有侵权,请联系作者删除!