Golang结构体基础

99 阅读3分钟

面向对象的引入

  1. 很多人说Go是面向对象的语言,Golang确实支持OOP,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。所以我们说Golang支持面向对象编程特性是比较准确的。
  2. Golang没有类(class),Go语言的结构体(struct)和其它编程语言的类(class)有同等的地位,你可以理解Gelang是基于struct来实现OOP特性的
  3. Golang面向对象编程非常简洁,去掉了传统OOP语言的方法重载、构造函数和析构函数、隐藏的this指针等等
  4. Golang仍然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其它OOP语言不一样,比如继承:Golang没有extends 关键字,继承是通过匿名字段来实现。

结构体的定义

有点Java基础的,下面的定义方式一看就懂了

type Teacher struct {
	// 变量名大写外界可以访问这个属性
	Name string 
	Age int
	School string
}
func main (){
	// 创建老师结构体的实例
	var t1 Teacher	// 这和定义变量是一样的(var a int)
	fmt.Println(t1)	// 在未赋值时默认是{ 0 }
	t1.Name = "赫敏·格兰杰"
	t1.Age = 15
	t1.School = "霍格沃兹"
	fmt.Println(t1)
}

结构体创建实例的4种方式

上述代码就是第一种创建方式,下面展示其它三种基本创建方式

type Teacher struct {
	Name string 
	Age int
	School string
}
func main (){
	var t1 Teacher	= Teacher{"赫敏·格兰杰",15,"霍格沃兹"}
	fmt.Println(t1)
}

第三种方式创建后实际上返回的是结构体的指针:

func main(){
	var t *Teacher = new(Teacher)
    // 这里t就是指向Teacher对象的地址,要想给Teacher实例的字段赋值,就要对地址t取值
	(*t).Name = "哈利"
	(*t).Age = 15
	fmt.Println(*t)
}

但是上面这种方式看起来有些麻烦,为了符合程序员的习惯,go提供了简化的赋值方式,如下:

func main(){
	var t *Teacher = new(Teacher)
	t.Name = "哈利"	// Go的编译器底层帮你实现了上面的转化过程
	t.Age = 15
	fmt.Println(*t)
}

接下来看方式四,返回的同样是结构体的指针

func main(){
	var t *Teacher = &Teacher{"哈利",15}
	fmt.Println(*t)
}

这就是指针部分的基础内容,&是对变量取地址,*和 & 可以互相抵消。

结构体之间的转换

结构体是用户单独定义的类型,和其他类型进行转换时需要具有完全相同的字段(名字、个数、类型)

package main

import "fmt"

type Student struct {
	Age int
}
type Person struct {
	Age int
}
func main (){
	var s Student = Student{10}
	var p Person = Person{15}
	s = Student{p}	// 主要需要使用规定的强制转换,s = p是不行的
	fmt.Println(s)
	fmt.Println(p)
}

程序输出

{15}

{15}

注意: 如果我们对同一个结构体进行重新定义(相当于取别名),例如:type Stu Student,尽管他们是一个东西,GoLang会认为这是新的数据类型,二者之间仍然需要强制的转换。