结构体
与其他语言中类相类比。
属性访问权限
众所周知,Go是用首字母大小写来控制访问权限的(虽然它内建函数都是用小写),结构体属性访问权限在序列化成json时可以很容易的观察到。如下:
type People struct {
Name string //`json:"name-2"`
Color, Nation string
Gender string
age int
}
...
func Test_b(t *testing.T) {
var p People
p.Name = "Jerry"
p.age = 12
p.Gender = "F"
p.Nation = "EN"
data, err := json.Marshal(p)
if err != nil {
t.Error(err)
}
t.Log("json data : " ,string(data[:]))
}
//out:{"Name":"Jerry","Color":"","Nation":"EN","Gender":"F"}
可以看到小写的age
没有出现在序列化结果里,没有赋值的Color
属性都出现了。
反序列化也是这样的规律。
添加序列化别名的注意点
上面示例代码中的`json:"name2"即是给序列化时取个别名,输出结果为:
{"name-2":"Jerry","Color":"","Nation":"EN","Gender":"F"}。 但是对于
Color, Nation string `这样定义的字段,则无法添加别名;强化添加,这一行的字段都不会被序列化。
匿名字段与“继承”
普通的匿名字段就是以其类型名作为字段名的简化方法,如下:
type Dog struct {
string
int
}
func Test_anonymity1(t *testing.T) {
d := Dog{}
d.int = 12
d.string = "sdf"
t.Log(d)
}
//out:{sdf 12}
但这种方法只能一种类型用一次。这种方法主要还是用在“继承”属性访问上。
“继承”
据说Go的“继承”与通常意义上的继承不是太一样,具体概念上的细节暂不深究。
type Teacher struct {
People
name string
Gender string
age int
}
...
func Test_anonymity2(t *testing.T) {
//p := People{Name: "Jerry", Gender: "F", age: 12, Color: "red"}
tc := Teacher{People{"Jerry", "red", "CN", "F", 12},
"Tom", "M", 90}
t.Log(tc)
t.Log(tc.name,tc.Color,tc.Name,tc.age,tc.Gender)
}
//out:{{Jerry red CN F 12} Tom M 90}
//out:Tom red Jerry 90 M
用结构体作匿名字段初始化时候是真的有点难受。
在处理两个结构体有相同的字段名时与其他语言中继承的规则是相同的。
方法的“继承”
func (*People) say() {
fmt.Println("People say....")
}
func (*Teacher) say() {
fmt.Println("Teacher say...")
}
添加这两个方法,随便注释掉其中一个,就可以看出方法“继承”的规律。与Java等语言是一致的。
属于结构体(类)的函数被称之为方法。这两个词并没有严格区分,混用也不是大问题