Go语言学习笔记4——struct

        原计划这篇是写函数的,翻来覆去的研究函数,也没找到什么感悟,于是就写struct吧。这可是个好家伙阿,一个非玩具的C系统中,绝对是struct的天下,可Go更是青出于蓝胜于蓝。

        struct在Go中基本总是和type一起出现,Go的type关键字相似于C中的typedef,给一个变量定义个别名。

先欣赏一段struct的代码:

package main

import "fmt"

/**
 * 定义Person类
 */
type Person struct {
    name string
    age  int
}

/**
 * 为Person类定义方法
 */
func (this *Person) SetName(name string) {
    this.name = name
}

func (this *Person) GetName() string {
    return this.name
}

func (this *Person) SetAge(age int) {
    this.age = age
}

func (this *Person) GetAge() int {
    return this.age
}


/**
 * 定义Girl类, 继承于Person
 */
type Girl struct {
    Person
    gender string
}

func (this *Girl) SetGender(gender string) {
    this.gender = gender
}

func (this *Girl) GetGender() string {
    return this.gender
}


func main() {
    p1 := new(Person)
    p1.SetName("yixiao")
    p1.SetAge(25)

    fmt.Printf("Name: %s, Age: %d\n", p1.GetName(), p1.GetAge())


    var p2 Person
    p2.SetName("wxw")
    p2.SetAge(23)

    fmt.Printf("Name: %s, Age: %d\n", p2.GetName(), p2.GetAge())

    var g Girl
    g.SetName("lili")
    g.SetAge(12)
    g.SetGender("girl")

    fmt.Printf("Name: %s, Age: %d, Gender: %s\n", g.GetName(), g.GetAge(), g.GetGender())
}

         我相信java和C++程序员看到这段代码绝对有一种似曾相识的感觉。封装的数据之上还能提供操作的方法,这就是最基本的面向对象。虽然Go支持一定的面向对象编程,但我们必须得清楚它不是一门OO的语言,仅仅是一门命令式的语言,和C一样。上面代码的mian函数中使用了两种定义Person对象的方法,第一个其实是指针,第二个才是变量,但两种方式都可以用同一种途径来访问其方法,这是Go语言所允许的,如果你是一个C程序员,你可能会非常的惊讶。

         上面的代码中也有继承的关系,这都是面向对象编程的基本技术,可我个人还是趋向于尽量避免使用继承,能不用就不用,所有Go支持继承并没有让我为此而兴奋,不过语言级支持为封装的数据类提供方法倒是非常不错的,这就满足很大一部分用C++的类写着C程序的人。因为他们只要简单的数据和方法的封装,不要多态,更不要泛型等。

(纠正:这里准备的说不应该是继承,应该是组合,类型的组合,虽然效果相似于继承。我记得C++程序员就经常争论究竟是用继承还是用组合。)

         一个合格的C++程序员绝对不是用C++写着C程序,他们需要熟悉各种奇迹淫巧,需要对C++类的内存分布了如指掌。一个再复杂的类,你只要给他一支笔和一张纸,他就能给你画出各种成员变量,各种方法,虚函数,纯虚函数的内存分布,并且还能清楚的阐述虚函数表的性能等问题。时至今日,我早已经将虚函数,纯虚函数,甚至虚函数表等东东忘得一干二尽了。这些东西根本不是用来帮助你写出优雅的程序,而是阻碍着你,让你一辈子都无法洞悉小的优雅。


面向对象的精髓在于抽象,万物被过度抽象的结果就是迷失自我。



你可能感兴趣的:(Google开源)