Java 编程中,class 使用是非常高频的,那么 Golang 中,是否有类似的概念呢?
其实,Golang 中并没有 class 的替代实现,只有结构体和扩展方法,考虑如下代码:
package person
import (
"fmt"
)
type Man struct {
Name string
Age int
Sex string
}
func (man *Man) SayHello() {
fmt.Print("I'm a man my name is " + man.Name + " and my age is ")
fmt.Println(man.Age)
}
func (man *Man) SetName(name string) {
man.Name = name
}
func (man *Man) SetAge(age int) {
man.Age = age
}
这里,我们定义了一个结构体 Man,有 Name、Age、Sex 三个字段,之所以不使用 name、age、sex 是因为 Golang 中,首字母大写的是 public,这点也不同与 Java,再看后面的三个方法,这就是扩展方法,这里man *Man
中,* 号的含义是,传递的是指针,指针指向对象,修改对传递进来的对象生效,如果传入的是 man Man
则传递的是值,修改仅在当前方法内有效,不会修改调用者传递的对象。
Golang 没有 class,如果一定说有,那就是结构体,但结构体仅存储数据,没有方法,不过你可以扩展方法,扩展后使用时和 java 一样,考虑如下代码:
package main
import (
"kpromise/person"
)
func main() {
var man = &person.Man{Name: "chun", Age: 32}
man.SayHello()
man.SetName("chun2")
man.SetAge(13)
man.SayHello()
}
我们发现,对于 man 的使用,Golang 和 java 似乎一样,都是 man.xxx 调用相关方法,不同的是创建对象,Golang 由于是创建结构体,其结构更像 json,前面的 & 符号表示,创建的是指针。
相比之下 Golang 其实更简洁且维护也更容易,class 被拆分为了 结构体和扩展方法,但是 Golang 的扩展方法不同于 JavaScript 那样,你只能在包内扩展,无法包外扩展,且这是其设计理念内的,不会修改,指针这个概念,上次听到它,记不得是 C 还是 C# 了,Golang 引入它,可以避免结构体被修改,如果修改,则在当前结构体的生命周期内修改,这一点喜人。
另外,结构体可以嵌套结构体或结构体指针,嵌套类似 Java 的继承;需要注意的是,如果嵌套了一个结构体指针,且其值为 nil,此时该结构体指针的扩展方法也可以使用(假设扩展方法的 receiver 是指针),但由于是 nil,如果该方法里面读取结构体的值,则 panic,这点非常特殊,Java 不存在判空后,出现空指针的情况,Golang 可能会出现。
评论