创建 struct
在 Go 语言的结构体(struct)和其他语言的类(class)具有同等地位。但是绝对不是一个东西。我们尽量不要用过语言来翻译新的语言的某些语法。在 go 语言中放弃了继承而保留了组合。
type Person struct {
name string
age int
}
通过 type 关键字定义一个 struct ,struct 定义数据结构最早是在 c++ 中看到和了解到 struct 的。定义 struct 结构包括哪些属性,并且指定属性的类型,是以单行的形式声明的,大家可能注意到了其结尾没有逗号分隔。
首字母大写在 go 语言中有着特殊含义
如何实例化 struct
p1 := new(Person)
p2 := &Person{}
p3 := &Person{
name: "zidea",
age: 35,
}
p := Person{
"zidea",
35,
}
实例化 Person 很简单,struct 名称后面紧跟一对花括号,在花括号中定义名称。然后可以通过(.)来调用对象 p 的属性。
在 go 语言中显式初始化的变量都会被初始化为该类型的零值。在 Go 语言中没有构造函数的概念,对象的创建通常交给由一个全局的创建函数来完成,以 NewXXX 来命名,表示“构造函数”。
func NewPerson(name string,age number) *Person{
return &Person{name,age}
}
p.name= "zidea"
type Person struct{
name string
tuts []string
age int
}
当为 Person 添加字段 tuts 这时如果没有更新 p 就会在编译时候发生错误
/main.go:31:3: cannot use 35 (type int) as type []string in field value
./main.go:31:3: too few values in Person literal
但是当我们显示地进行赋值就不会发生这样错误。
在 go 语言属性名称首字母大写是有特殊意义,首字母大写表示该字段在其他 package 是可以访问到该属性,类似 java 中 public。
type Person struct{
Name string
Tuts []string
Age int
}
struct 是可以进行嵌套的
type person struct {
name string
age int
contact struct {
phone, city string
}
}
字面量初始化
也可以通过字面值进行初始化,这是常用的做法,写法类似于JSON的写法
type Person struct {
name string
age int
}
p := Person{
name:"zidea",
age: 30,
}
结构体作为参数传递
定义函数接受参数为 Person 注意在 go 默认是传值的
func print(p Person){
fmt.Println(p.name)
fmt.Println(p.age)
}
print(p)
结构体指针
如果要在函数 print 中修改作为参数传入的 person 对象,就需要传地址而非传值
p := &Person{
name:"zidea",
age: 30,
}
func print(p *Person){
fmt.Println(p.name)
fmt.Println(p.age)
}
匿名结构体
a := &struct{
name string
age int
}{
name:"zidea",
age: 30,
}
结构体的继承
在 go 语言中放弃了继承而保留了组合,而这种组合是匿名的,也称为匿名组合。
type Base struct{
Name string
}
func (base *Base) Foo(){
fmt.Println("call Foo method of Base")
}
func (base *Base) Bar(){
fmt.Println("call Bar method of Base")
}
type Foo struct{
Base
}
func (foo *Foo) Bar(){
fmt.Println("call Bar method of Foo")
foo.Base.Bar()
}
func main() {
f := Foo{}
f.Bar()
}
上面代码定义了 Base 基类,为 Base 基类添加两个方法 Foo 和 Bar,然后定义了一个 Foo 类,在 Foo 类上改写了 Bar() 方法。