Go面向对象二之结构体字段(属性)
字段是结构体的一个组成部分,一般的数据类型、数组,引用类型等都是字段。
一:字段使用细节说明
①:字段声明方式与普通声明略有区别,如:字段Name string即可;
②:字段声明后没有赋值使用默认值,如引用类型默认值就是nil;
③:举例1
string默认为空字符串,[ ]和map[ ]实质也是nil。
④:举例2
由下代码可知使用切片和map还需要make或同等作用的赋值才行。
package main import ( "fmt" ) //结构体 type Jgt struct { Name string Num int Arr [3]int Prt *int Slice []int M map[string]string } func main() { var jgt Jgt jgt.Name = "test1" fmt.Printf("jgt.Name=%v\n",jgt.Name) jgt.Num = 10 fmt.Printf("jgt.Num=%v\n",jgt.Num) jgt.Arr = [3]int{1,2,3} fmt.Printf("jgt.Arr=%v\n",jgt.Arr) jgt.Prt = &jgt.Num fmt.Printf("jgt.Prt=%v\n",*jgt.Prt) jgt.Slice = make([]int, 3) jgt.Slice[0] = 11 fmt.Printf("jgt.Slite=%v\n",jgt.Slice) jgt.M = map[string]string{ "name" : "louis", "age" : "18", "sex" : "male", } fmt.Printf("jgt.M=%v\n",jgt.M) } [ `go run struct1.go` | done ] jgt.Name=test1 jgt.Num=10 jgt.Arr=[1 2 3] jgt.Prt=10 jgt.Slite=[11 0 0] jgt.M=map[name:louis age:18 sex:male]
⑤:不同结构体变量的修改,互不影响
由上可知,不同的结构体变量在内存中使用不同的内存空间。
二:结构体变量访问结构体字段的四种方法
①:var 结构体变量名称 结构体
如:var jgt Jgt
②:var 结构体变量名称 结构体=结构体{}
举例
package main import ( "fmt" ) //结构体 type Jgt struct { Name string Age int } func main() { var jgt Jgt=Jgt{"张三",18} fmt.Println(jgt) }
结果 [ `go run struct1.go` | done ] {张三 18}
③:var 结构体变量名称 *结构体=new(结构体)
举例
package main import ( "fmt" ) //结构体 type Jgt struct { Name string Age int } func main() { var jgt *Jgt = new(Jgt) //因为jgt为指针所以要用指针方式赋值和输出如:(*jgt).Name = "张三" //但由于Go在底层做了优化,会自动在前面加*,故也可以使用普通方法jgt.Age = 18 (*jgt).Name = "张三" jgt.Age = 18 //因为jgt为指针,如果使用不带*号输出前面会有&符号 //正常添加*号能解决&符号问题 fmt.Println(jgt) fmt.Println(*jgt) } 结果 [ `go run struct1.go` | done ] &{张三 18} {张三 18}
④:var 结构体变量名称 *结构体 = &结构体{}
举例
package main import ( "fmt" ) //结构体 type Jgt struct { Name string Age int } func main() { var jgt *Jgt = &Jgt{"张三", 18} (*jgt).Age = 19 fmt.Println(*jgt) } 结果 [ `go run struct1.go` | done ] {张三 19}
备注:其中③④方式返回的是结构体指针。
三:结构体字段使用细节
①:结构体变量里的字段在内存中是连续的。
②:结构体之间是可以相互转换,但需要有完全相同的字段
package main import ( "fmt" ) //结构体 type A struct { Name string } type B struct { Name string } func main() { var a A var b B b = B(a) fmt.Println(a, b) }
③:结构体通过type重新定义,在Golang中被认为是一个新的类型,但仍然可以进行转换(参考第②点)
④:每个字段都可以写上tag,该tag可以通过反射机制获取,从而实现序列化和反序列化
举例
package main import ( "fmt" "encoding/json" ) //结构体 type Student struct { Name string `json:"name"` //`json:"name"` 就是tag,规定了序列化的格式 Age int `json:"age"` } func main() { var stu Student = Student{"张三", 18} json_str, err := json.Marshal(stu) if err != nil { fmt.Println("json数据失败") } fmt.Println(string(json_str)) } 结果 [ `go run struct1.go` | done ] [123 34 110 97 109 101 34 58 34 229 188 160 228 184 137 34 44 34 97 103 101 34 58 49 56 125] {"name":"张三","age":18}