本人原来是写JAVA的, 大学四年期间从大二到大四都在用JAVA, 现在由于某些原因需要学习一下GO, 因此开了一个新的专栏来记录JAVA转GO的一些心得, 小弟文笔不佳, 写博客的经验也比较少, 可能表述的不是特别清晰, 若文章中有错误的地方希望各位大佬能够指出.
结构体
GO虽然也是一门面向对象的语言, 但是与JAVA和C++不同, GO中并没有Class关键字, 而是用struct代替, 以下列出struct与class之间的一些区别.
结构体的声明
在GO之中用 type Name struct{} 的方式声明一个结构体,如下
type Dog struct{
name string
}
上边这段代码定义了一个Dog结构体, 包含了一个name字段, name的类型为string.
go语言中变量的定义比较特殊, 用 变量名 类型
的方式声明一个变量, 这一点在初接触时可能会非常不适应.
定义结构体的方法
在GO中, 定义成员方法的方式与JAVA不同, 是在结构体之外定义的, 如下
func (d Dog) sleep() {
fmt.Printf("Dog %s is sleeping", d.name)
}
上边这段代码给Dog这个结构体定义了一个 sleep() 方法, 其中方法名前的括号可以理解为这个方法的接收者, 之后我们便可以通过 d.sleep() 的方式调用这个结构体的成员方法
func main(){
d := Dog{name: "snoopy"}
d.sleep()
}
接口
接口的声明
在GO中, 声明接口的方式为
type Sleeper interface{
sleep()
}
上边这段代码定义了一个名为Sleeper的接口, 而其他结构体想要实现这个接口只需要实现这个接口中的方法即可, 如下
func (d Dog) sleep() {
fmt.Printf("Dog %s is sleeping", d.name)
}
可以在main方法中测试一下是否可以将Sleeper转换为Dog
func main(){
var s Sleeper
s = Dog{name: "snoopy"}
s.sleep()
}
可以看到, 在main方法中首先声明了一个Sleeper接口类型s, 然后将s实例化为一个Dog对象, 并且调用了s的sleep()方法, 执行结果如下:
Dog snoopy is sleeping
Go中继承的实现(嵌入)
不同于JAVA, Go中并非使用extends关键字继承某个类, 而是通过嵌入的方式实现继承, 如下边中的代码, 通过将Animal结构体嵌入Dog结构体中, 实现Dog结构体继承Animal结构体的字段和方法
type Animal struct{
age int
gender int
}
type Dog struct{
Animal
name string
}
func (a Animal) bark(){
fmt.Println("animal is barking!")
}
func (d Dog) bark(){
fmt.Println("Wooo")
}
之后可以在Dog类型的变量中调用Animal的变量和方法
func main(){
dog := Dog{name: "snoopy"}
fmt.Printf("The age of snoopy is %d \n", dog.age) // 未赋值 Go中int类型的默认值位0, string为空字符串
dog.age = 7
fmt.Printf("The age of snoopy is %d \n", dog.age) // 已赋值
dog.Animal.bark()
dog.bark()
}
结果:
The age of snoopy is 0
The age of snoopy is 7
animal is barking!
Wooo
序列化
在JAVA中, 如果我们要将一个类持久化必须使这个类实现Serializable
接口, 也就是序列化, 在Go中, 序列化的方式如下:
type Dog struct{
Name string `json:"name"`
Age int `json:"age"`
}
注意这里变量的命名必须大写开头, 否则后边序列化之后会丢失, 目前暂时不知道为什么, 希望有知道原因的大佬可以在评论区指出
func main(){
d := Dog{Name: "snoopy", Age: 7}
dJson, err := json.Marshal(d)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(dJson))
}
执行结果:
{"name":"snoopy","age":7}