一、Golang 如何面向对象

1. 1 new 、& 和 * 的关系

  • &type: 取指向 type 的内存地址,类似 C/C++的。
  • new(type):初始化对象,对象的属性初始化int => 0, string => ""返回指向 type 内存的地址(pointer),类似面向对象 C++、JAVA 返回地址(pointer)。
  • *type 1. 在定义变量的时候是指”指向这个类型变量的指针” 2. *variable 解引用指向这块内存的存储的值
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
type Cat struct {
	nik string
	age int
}

func updateName(c *Cat, nik string) {
	// 可以省略 (*)
	(*c).nik = nik
}

func main() {
	var d1 = &Cat{}
	fmt.Printf("my name is %s, my age is %d\n", d1.nik, d1.age)
	updateName(d1, "A")
	fmt.Printf("my name is %s, my age is %d\n", d1.nik, d1.age)
	var d2 = new(Cat) // equal with var d1 = &Cat{}
	fmt.Printf("my name is %s, my age is %d\n", d2.nik, d2.age)
	d2.nik = "Hello"
	fmt.Printf("my name is %s, my age is %d\n", d2.nik, d2.age)
}

1.2 模拟面向对象

Golang 是没有继承类,继承这些面向对象的概念的,但是有可以用structkeyword 来实现类似类

先用 Python 来写一个 class 和方法

1
2
3
4
5
6
class Dog:
    def __init__(self, nik):
        self.nik = nik

    def greet(self, other):
        print("Hi {} I'm {}".format(other, self.nik))

再使用 Golang 来改写

  • struct-field 的方式模拟类和属性
  • 通过 Struct-function 的方式模拟方法
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 初始化构造函数
func NewDog(nik string) *Dog {
	return &Dog{name: nik}
}

// 结构体定义方法
func (d *Dog) greet(other string) {
	fmt.Printf("Hi %s I'm %s", other, d.name)
}

func main() {
	var d = NewDog("wangcai")
	d.greet("Qi")
    // Hi Qi I'm wangcai
}

1.3 Struct 定义变量

Struct-filed 包含指向自己的指针

  • (* pointer).value == pointer.value golang 自己优化,不管是指针还是结构体本身直接用.来访问, 这样就非常 nice 了,写的非常舒心。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
type Node struct {
	value int
	next  *Node
}
func main() {
    var n1 = &Node{value: 1, next: &Node{value: 2}}
	fmt.Println((*n1).value)
	// 省略写法
	fmt.Println(n1.value)
	fmt.Println((*(*n1).next).value)
	// 省略写法
	fmt.Println(n1.next.value)
	fmt.Printf("n1 value %d next= %v", n1.value, n1.next)
}