struct

陆人知 · · 569 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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)
}


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:陆人知

查看原文:struct

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

569 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传