golang中结构体

Posted Leo Han

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 = 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中结构体的主要内容,如果未能解决你的问题,请参考以下文章

Golang 入门 : 结构体(struct)

golang中级进阶(二):结构体

golang中返回空结构体可以返回nil吗

golang中定义的某个interface作为函数的入参时

换个语言学一下 Golang ——结构体和接口

Golang 结构体(struct)