19
struct
source link: https://studygolang.com/articles/31505
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
1、声明
type human struct { name string age int height int } var h human fmt.Printf("%p,%v\n",&h,h)
0xc000004460,{ 0 0}
简化写法
type human struct { name string age,heignt int }
使用new
type human struct { name string age,heignt int } h :=new(human) fmt.Printf("%p,%v\n",h,h)
0xc00005c420,&{ 0 0}
2、实例化
type human struct { name string age int height int } var h1 human h1.name="张三" h1.age=20 h1.height=180 h2:=human{"李四",21,175} var h3=human{"王五",20,181} h4:=human{ name:"赵六", age:22, height:175, } h5:=human{ name:"赵六", height:175, } fmt.Println(h1,h2,h3,h4,h5)
{张三 20 180} {李四 21 175} {王五 20 181} {赵六 22 175} {赵六 0 175}
3、结构体方法
GO的方法是下定义在一个接收者上的一个函数,接收者是某种类型的变量;GO的方法其实就是一个变种的函数
func (接收者) 函数名... 正常的函数结构
值传递
package main import ( "fmt" ) type human struct { name string age int height int } func (h human) change(name string){ h.name=name fmt.Println(h) } func main() { h1:=human{ name:"张三", age:22, height:175, } fmt.Println(h1) h1.change("李四") fmt.Println(h1) }
{张三 22 175} {李四 22 175} {张三 22 175}
引用传递
package main import ( "fmt" ) type human struct { name string age int height int } func (h *human) change(name string){ h.name=name fmt.Println(*h) } func main() { h1:=human{ name:"张三", age:22, height:175, } fmt.Println(h1) h1.change("李四") fmt.Println(h1) }
{张三 22 175} {李四 22 175} {李四 22 175}
4、匿名成员
字段的继承,如下,student可以直接方案human的字段name、age、height
type human struct { name string age int height int } type student struct { human grade string } func main() { stu1:=student{ human{"小明",8,140},"三年级", } fmt.Println(stu1) fmt.Println(stu1.name,stu1.age,stu1.height,stu1.grade) }
{{小明 8 140} 三年级} 小明 8 140 三年级
所有的内置类型和自定义类型都是可以作为匿名字段
type human struct { name string age int height int } type student struct { human grade string string } func main() { stu1 := student{ human{"小明", 8, 140}, "三年级", "中关村一小", } fmt.Println(stu1) fmt.Println(stu1.name, stu1.age, stu1.height, stu1.grade, stu1.string) }
{{小明 8 140} 三年级 中关村一小} 张三 8 140 三年级 中关村一小
字段重载
type student struct { human grade string string name string } func main() { stu1 := student{ human{"小明", 8, 140}, "三年级", "中关村一小", "张三", } fmt.Println(stu1.name,stu1.human.name) }
张三 小明
匿名字段的方法
type human struct { name string age int height int } type student struct { human grade string string name string } func (h *human)change(name string) { h.name=name fmt.Println(*h) } func main() { stu1 := student{ human{"小明", 8, 140}, "三年级", "中关村一小", "张三", } stu1.change("大明白") fmt.Println(stu1.name,stu1.human.name) }
{大明白 8 140} 张三 大明白
5、匿名结构体
h1:= struct { name string age int height int }{ name:"张三", age:22, height:175, } fmt.Println(h1)
{张三 22 175}
结构体内嵌匿名结构体
type User struct { RealName string Age int Cart struct { Brand string Price float64 } } func main() { var u User u.Age=19 u.RealName="小明" u.Cart.Brand="奔驰" u.Cart.Price=100 fmt.Println(u) }
{小明 19 {奔驰 100}}
结构体内嵌匿名结构体数组
数组不是要有数量吗?
type User struct { RealName string Age int Carts []struct { Brand string Price float64 } } func main() { var u User u.Age=19 u.RealName="小明" u.Carts = []struct { Brand string Price float64 }{ {Brand:"本田",Price:100000.00}, {Brand:"宝马",Price:300000.00}, } fmt.Println(u) }
{小明 19 [{本田 100000} {宝马 300000}]}
type User struct { RealName string Age int Carts []struct { Brand string Price float64 } } func main() { user := User{} user.RealName = "张三" user.Age =40 brands:=[]string{"奔驰","宝马","丰田","大众"} for _, cart := range brands { item := struct { Brand string Price float64 }{Brand:cart,Price:100} user.Carts = append(user.Carts, item) } fmt.Println(user) }
{张三 40 [{奔驰 100} {宝马 100} {丰田 100} {大众 100}]}
可见性
6、tag
在golang中,命名都是推荐都是用驼峰方式,并且在首字母大小写有特殊的语法含义:包外无法引用。但是由经常需要和其它的系统进行数据交互,例如转成json格式,存储到mongodb啊等等。这个时候如果用属性名来作为键值可能不一定会符合项目要求。
Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来。 Tag在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下:
key1:"value1" key2:"value2"
下面的例子中Name和Age按照tag中json的格式输出了,Height原样输出。
package main import ( "encoding/json" "fmt" ) type human struct { Name string `json:"name"` Age int `json:"age"` Height int } func main() { var user1 human user1.Name = "测试名" user1.Age=20 user1.Height = 180 u,err:=json.Marshal(user1) if err == nil{ fmt.Printf("value: %s", u) } }
{"name":"测试名","age":20,"Height":180}
获取tag
h:=&human{"测试名",20,180} rf:=reflect.TypeOf(h) tag := rf.Elem().Field(0).Tag fmt.Println(tag) field0 := rf.Elem().Field(0) fmt.Println(field0.Tag.Get("json"))
json:"name" name
7、复制
struct是值类型,默认的复制就是深拷贝
h1:=human{"测试名",20,180} h2:=h1 fmt.Printf("%p,%v\n",&h1,h1) fmt.Printf("%p,%v\n",&h2,h2)
0xc000004460,{测试名 20 180} 0xc000004480,{测试名 20 180}
直接赋值指针地址
h1:=human{"测试名",20,180} h3:=&h1 fmt.Printf("%p,%v\n",&h1,h1) fmt.Printf("%p,%v\n",h3,*h3)
0xc000004460,{测试名 20 180} 0xc000004460,{测试名 20 180}
8、函数传参
值传递
type human struct { Name string `json:"name"` Age int `json:"age"` Height int } func change(h human) { h.Name="姓名" fmt.Printf("%p,%v\n",&h,h) } func main() { h1:=human{"测试名",20,180} fmt.Printf("%p,%v\n",&h1,h1) change(h1) fmt.Printf("%p,%v\n",&h1,h1) }
0xc00005c420,{测试名 20 180} 0xc00005c480,{姓名 20 180} 0xc00005c420,{测试名 20 180}
引用传递
func change(h *human) { h.Name="姓名" fmt.Printf("%p,%v\n",h,*h) } func main() { h1:=human{"测试名",20,180} fmt.Printf("%p,%v\n",&h1,h1) change(&h1) fmt.Printf("%p,%v\n",&h1,h1) }
有疑问加站长微信联系(非本文作者)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK