golang中结构体
Posted Leo Han
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang中结构体相关的知识,希望对你有一定的参考价值。
golang其实并不是一个完全意义上的面向对象语言,其实现面向对象的多态主要基于接口和结构体实现。
在golang中结构体与c/c++中的结构体类似,用来定义复杂的数据类型,一般结构体定义如下:
type StructName struct
fieldName1 type1
fidldName2 type2
...
需要注意的是:
- 结构体的包名在同一个包内必须唯一,不能重复
- 结构体的字段必须唯一,不能重复
- 同类型的结构体字段可以放在一行定义
一般结构体实例化可以通过如下方式:
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 = Orderamount:10,price:12.5,address:"BeiJing,China"
// 或者
// order = Order10,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 := Productname:"奥利奥",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 := Productname:"奥利奥",price:10.5
address := Address"中国","北京市","北京市","海淀区"
var order Order
order.Product=product
order.Address=address
order.amount=10
fmt.Println(order.getInfo()) // order
这时候结构体和匿名字段拥有同样的方法,可以理解为面向对象的方法重写override
以上是关于golang中结构体的主要内容,如果未能解决你的问题,请参考以下文章