golang中结构体

golang其实并不是一个完全意义上的面向对象语言,其实现面向对象的多态主要基于接口和结构体实现。
在golang中结构体与c/c++中的结构体类似,用来定义复杂的数据类型,一般结构体定义如下:

type StructName struct{
    fieldName1 type1
    fidldName2 type2
    ...
}

需要注意的是:

  1. 结构体的包名在同一个包内必须唯一,不能重复
  2. 结构体的字段必须唯一,不能重复
  3. 同类型的结构体字段可以放在一行定义

一般结构体实例化可以通过如下方式:

type Order struct {
	amount int
	price float64
	address string
}

func main() {
	// example1 这种情况下order的字段都是对应的默认零值
	var order Order
	order.amount = 10
	order.price = 12.5
	order.address = "BeiJing,China"
	

	// example2 这种情况下同时初始化了order的属性字段
	order = Order{amount:10,price:12.5,address:"BeiJing,China"}
	// 或者
	// order = Order{10,12.5,"BeiJing,China"}

	// example3 通过new方式创建,返回的是该结构体的指针,且属性字段都是默认零值
	orderPtr := new(Order)
	// 等价于 orderPtr := &Order{}
	orderPtr.amount = 10
	orderPtr.price = 12.5
	orderPtr.address = "BeiJing,China"
}


我们需要注意的一点是,golang中的结构体是值类型,也就是如果只是单纯的结构体类型而不是指针类型都是值传递,需要通过拷贝复制。
这里说下golang中的拷贝复制:深拷贝浅拷贝
所谓的深拷贝就是将原值的内存内容拷贝到一个新的内存地址中去
所谓的浅拷贝,一般是针对指针类型,就是拷贝的不是值的内存地址,而是指针的内容
其实说白了,golang中只有值传递,所谓的深拷贝和浅拷贝,拷贝的都是值,只不过一个是实际类型的数据内容,一个只是指针内容,如果结构体比较复杂,字段属性比较多,
那么直接基于值的深拷贝肯定耗时多,而基于指针的浅拷贝则快速很多(指针一般都是4字节或8字节)

匿名结构体

与函数一样,结构体也有匿名结构体:

order2 := struct {
		amount int
		name string
}{10,"rice"}
结构体匿名字段

所谓结构体匿名字段,也就是结构体中存在的仅有类型而没有命名的字段,比如:

type Order2 struct {
	int
	string
	price float64
	address string
}

需要注意的是,在一个结构体中,同一个类型只能由一个匿名字段

结构体通过匿名字段可以实现类似继承关系:

type Product struct {
	price float64
	name string
}
type Address struct {
	country,province,city,street string
}
type Order struct {
	Product
	Address
	amount int
}

golang中结构体的匿名字段的方法时可以继承的:


type Product struct {
	price float64
	name string
}
func (p Product) getProductInfo() string {
	return fmt.Sprintf("%f %s",p.price,p.name)
}
type Address struct {
	country,province,city,street string
}
type Order struct {
	Product
	Address
	amount int
}


type Order2 struct {
	int
	string
	price float64
	address string
}

func main() {
	product := Product{name:"奥利奥",price:10.5}
	address := Address{"中国","北京市","北京市","海淀区"}
	var order Order
	order.Product=product
	order.Address=address
	order.amount=10

	fmt.Println(order.getProductInfo())

}

另外golang中的匿名字段访问就是该字段对应的类型名称(实际上所谓的匿名字段,只不过是golang给这个字段直接命名为其类型对应的名称)

如果匿名字段和当前结构体方法有同名的,那么调用该结构体的方法:

type Product struct {
	price float64
	name string
}
func (p Product) getInfo() string {
	return fmt.Sprintf("%f %s",p.price,p.name)
}
type Address struct {
	country,province,city,street string
}
func (address Address) getInfo() string {
	return fmt.Sprintf("%s-%s-%s-%s",address.country,address.province,address.city,address.street)
}
type Order struct {
	Product
	Address
	amount int
}
func (order Order) getInfo() string {
	return "order"
}


type Order2 struct {
	int
	string
	price float64
	address string
}

func main() {
	product := Product{name:"奥利奥",price:10.5}
	address := Address{"中国","北京市","北京市","海淀区"}
	var order Order
	order.Product=product
	order.Address=address
	order.amount=10

	fmt.Println(order.getInfo()) // order

}

这时候结构体和匿名字段拥有同样的方法,可以理解为面向对象的方法重写override

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值