1、面向对象初识
1.1、模拟构造函数
Go 和传统的面向对象语言如 Java 有着很大区别。结构体没有构造函数初始化功能,可以通过以下方式模拟:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | type Person struct { 	Name string 	Age int }
  func NewPersonByName(name string) *Person { 	return &Person{ 		Name: name, 	} }
  func NewPersonByAge(age int) *Person { 	return &Person{ 		Age: age, 	} }
  func main() { 	p := NewPersonByName("zs") 	fmt.Println(p)						 }
 
  | 
 
贴士:因为 Go 没有函数重载,为了避免函数名字冲突,使用了 NewPersonByName 和 NewPersonByAge 两个不同的函数表示不同的 Person 构造过程。
1.2 父子关系结构体初始化
Person 可以看做父类,Student 是子类,子类需要继承父类的成员:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | type Person struct { 	Name string 	Age int }
  type Student struct { 	Person 	ClassName string }
 
  func NewPerson(name string, age int) *Person { 	return &Person{ 		Name: name, 		Age: age, 	} }
 
  func NewStudent(classname string) *Student { 	p := &Student{} 	p.ClassName = classname 	return p }
 
  func main() { 	s := NewStudent("一班") 	fmt.Println(s)						 }
 
  | 
 
1.3、Go 中的面向对象初识
在 Go 中,可以给任意类型(除了指针)添加相应方法:
1 2 3 4 5 6 7 8 9 10
   | type Interger int
  func (i Interger) Less (j Interger) bool { 	return i < j }
  func main() { 	var i Interger = 1 	fmt.Print(i.Less(5)) }
 
  | 
 
2、方法
2.1、方法
Go 中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是 struct。  
方法的声明和调用:
1 2 3 4
   | func (recevier type) methodName(参数列表) (返回值列表){           return 返回值 }
 
  | 
 
方法与函数的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | type Person struct { 	Name string 	Age int }
 
  func run(p *Person, name string) { 	p.Name = name 	fmt.Println("函数 run...", p.Name) }
 
  func (p *Person)run() { 	fmt.Println("方法 run...", p.Name) }
  func main() {
  	 	p1 := &Person{ 		"ruyue", 		10, 	}
  	 	run(p1, "张三")			
  	 	p1.run()						 }
 
  | 
 
2.2、Go 方法本质
Go 的方法是一种作用于特定类型变量的函数,这种特定类型的变量叫做接收器(Receiver)。如果特定类型理解为结构体或者“类”时,接收器就类似于其他语言的 this 或者 self。
在 Go 中,接收器可以是任何类型,不仅仅是结构体,依此我们看出,Go 中的方法和其他语言的方法类似,但是 Go 语言的接收器强调方法的作用对象是实例。
方法与函数的区别就是:函数没有作用对象。
指针接收器传入的是 struct 本身,指针接收器可以读写 struct 中的内容,在方法结束后,修改都是有效的。
非指针接收器传入的是 struct 的 copy 副本,非指针接收器只能读取 struct 中的数据但是不能写入,如果写入的话也只是写入到 struct 的备份中而已。
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | type student struct { 	age int8 }
 
  func(s *student) ageAdd1() { 	s.age += 1 }
 
  func(s student) ageAdd2() { 	s.age += 1 }
  func main() { 	student := new(student)
  	student.ageAdd1() 	fmt.Println(student.age) 
  	student.ageAdd1() 	fmt.Println(student.age) 
  	student.ageAdd2() 	fmt.Println(student.age)  }
 
  | 
 
一般情况下,小对象由于复制时速度较快,适合使用非指针接收器,大对象因为复制性能较低,适合使用指针接收器,此时再接收器和参数之间传递时不进行复制,只传递指针。