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}

 

posted @ 2019-01-11 17:21  louis-sun  阅读(3325)  评论(0编辑  收藏  举报