1.结构体的声明方式和基本用法
结构体对于学习过c或者c++的小伙伴来说并不陌生,结构体与java中的类也是相类似的,结构体可以理解为多种数据结构的组合方式,下面我们先声明一个结构体类型并对他进行简单的使用:
package main
import "fmt"
// 定义一个结构体类型Fruits
type Fruits struct {
// 名称
name string
// 数量
number int
}
func main() {
// 声明一个Fruits结构体类型变量,变量名为bannana
var bannana Fruits
// 给属性值赋值
bannana.name = "ban"
bannana.number = 3
// 输出结构体的值
fmt.Println(bannana)
}
运行结果:
{ban 3}
以上为一个简单的结构体使用方式。在函数中传递结构体类型数据时,也存在值拷贝和地址传递问题,我们通过一个例子可以看看两者的区别:
package main
import "fmt"
// 定义一个结构体类型Fruits
type Fruits struct {
// 名称
name string
// 数量
number int
}
// 值拷贝的传参方式
func foo1(fruit Fruits) {
fruit.name = "orange"
}
// 指针的传参方式
func foo2(fruit *Fruits) {
fruit.name = "orange"
}
func main() {
// 声明一个Fruits结构体类型变量,变量名为bannana
var bannana Fruits
// 给属性值赋值
bannana.name = "ban"
bannana.number = 3
fmt.Println("before foo1")
fmt.Println(bannana)
foo1(bannana)
fmt.Println("after foo1 before foo2")
fmt.Println(bannana)
// 注意,这里要传入地址
foo2(&bannana)
fmt.Println("after foo2")
fmt.Println(bannana)
}
运行结果:
before foo1
{ban 3}
after foo1 before foo2
{ban 3}
after foo2
{orange 3}
可以看到,两种方式都试图修改bannana中name属性的值,但是只有指针传递(地址传递)的方式成功了,这也说明引用传递方式仅仅传递的是bannana的拷贝副本,所以在foo1中对bannana的修改并不会影响到main中bannana。
2.结构体绑定方法
学习过java的小伙伴知道,java的类不仅具有属性,还具有一些方法,如果要为struct类型的数据绑定一些方法应该如何设置呢,我们可以在方法名前面加入(this 结构体名)的方式,同理,如果想真正操作调用该方法的结构体类型,那就是(this *结构体名),我们给个例子:
type Fruits struct {
// 名称
name string
// 数量
number int
}
// Fruits结构体的绑定方法,引用(拷贝副本)
func (this Fruits) SetName(name string) string{
this.name = name
return "success"
}
// Fruits结构体的绑定方法,指针(值传递)
func (this *Fruits) SetName2(name string) string{
this.name = name
return "success"
}
func (this *Fruits) GetName() string {
return this.name
}
func (this *Fruits) Show() {
fmt.Println(*this)
}
func main() {
// 声明一个Fruits结构体类型变量,变量名为bannana
var bannana Fruits
// 给属性值赋值
bannana.name = "ban"
bannana.number = 3
bannana.Show()
bannana.SetName("orange")
bannana.Show()
bannana.SetName2("orange2")
bannana.Show()
}
运行结果:
{ban 3}
{ban 3}
{orange2 3}
(this Fruits)和(this *Fruits)的区别与之前说的类似,很明显(this *Fruits)形式才能成功设置name属性的值,原因这里不再过多解释,这里主要是介绍如何给结构体类型绑定对应的方法,我们可以看到,我们直接给结构体绑定了对应的方法,使用时只需要(结构体变量名.方法名)就可以调用该方法了。