Go 语言之 struct 结构体

struct 结构


  • Go中的struct与C语言中的struct非常相似,并且Go没有class
  • 使用type<Name> struct{} 定义结构,名称遵循可见性规则
  • 支持指向自身的指针类型成员
  • 支持匿名结构,可用作成员或定义成员变量
  • 匿名结构也可以用于map的值
  • 可以使用字面值对结构进行初始化
  • 允许直接通过指针来读写结构成员
  • 相同类型的成员可以进行直接拷贝赋值
  • 支持== 与 != 比较运算符,但不支持 > 或 <
  • 支持匿名字段,本质上是定义了以某个类型名为名称的字段
  • 嵌入结构作为匿名字段看起来像继承,但不是继承
  • 可以使用匿名字段指针

测试用例

//
package main

import "fmt"

//定义了一 个空的结构体
type st01 struct {
}

//定义一个非空的结构体
type person struct {
    Name string
    Age  int
}

func main() {
    personInfo := person{}
    personInfo.Age = 19
    personInfo.Name = "xiaoqiang"

    fmt.Println(personInfo)

    //------------------------------
    fmt.Println("=============================")
    //直接初始化   属于 字面值 初始化
    personInfo2 := person{Name :"spark01", Age: 19}
    fmt.Println(personInfo2)

}

结构体,按值传递

//结构体,按值 传递
package main

import "fmt"

//定义一个类型
type sparkInfo struct {
    SparkClusterName string
    SparkNodeNum     int
}

func main() {
    newSparkInfo := sparkInfo{
        SparkNodeNum:     8,
        SparkClusterName: "spark-test-001"}

    fmt.Println("main:\t", newSparkInfo)
    updateSparkInfo(newSparkInfo)
    fmt.Println("main:\t", newSparkInfo)

}

//同样,这里是值传递,内部的修改,并不会影响到 旧值的
func updateSparkInfo(sparkInfo sparkInfo) {
    sparkInfo.SparkNodeNum = 9
    fmt.Println("updateSparkInfo:\t", sparkInfo)
}

结构体,按地址传递

//结构体,按地址传递
package main

import "fmt"

type k8sInfo struct {
    K8sClusterName string //k8s集群的名称
    K8sClusterNumm int    //k8s集群的节点个数
}

func main() {
    k8sInfo := k8sInfo{
        K8sClusterNumm: 1,
        K8sClusterName: "k8s-test-001"}

    fmt.Println(k8sInfo)
    updateK8sClusterInfo(&k8sInfo)
    fmt.Println(k8sInfo)
}

//传递的是 地址,按地址传递
//修改了,旧的值
func updateK8sClusterInfo(info *k8sInfo) {
    info.K8sClusterNumm = 110

    fmt.Println("updateK8s:\t", info)
}

结构体,按地址传递

//结构体,按地址传递
package main

import "fmt"

type dockerInfo struct {
    DockerClusterName string
    DockerClusterNum int
}

func main() {
    //一般更习惯这种写法,
    //在初始化的时候,就直接获取地址
    //这样以后在调用的时候,就不需要添加&号了
    dInfo := &dockerInfo{
        DockerClusterNum:19,
        DockerClusterName:"docker-yizhuang"}

    fmt.Println("init docker:\t", dInfo)
    updateDockerInfo(dInfo)
    fmt.Println("after docker:\t", *dInfo)

}

func updateDockerInfo (info *dockerInfo) {
    info.DockerClusterNum = 80
    fmt.Println("udpateDocker:\t", info)
}

匿名结构

//匿名结构
package main

import "fmt"

func main() {

    //创建一个匿名结构,
    //并且进行了初始化
    //而且,直接获取地址&
    ftp := &struct {
        FtpName string
        FtpNum int
    }{
        FtpName:"ftp-beijing",
        FtpNum:8}

    fmt.Println(ftp)
    fmt.Println(*ftp)
    fmt.Println("FtpName:\t", ftp.FtpName)
    fmt.Println("FtpNum:\t", ftp.FtpNum)

}

匿名结构, 嵌套进别的结构体里

//将匿名结构,嵌套进别的结构体里
package main

import "fmt"

type hadoop struct {
    HadoopClusterName string
    HadoopClusterNum  int
    //创建一个匿名结构
    HadoopOtherInfo struct {
        //同样,当多个变量都一样的时候,也可用省略
        //这是Go语言的优点
        HadoopVersion, HadoopUrl string
    }
}

func main() {
    hdfs := &hadoop{
        HadoopClusterName: "Hadoop-test-001",
        HadoopClusterNum:  9}

    //只能通过这种方式,进行初始化
    hdfs.HadoopOtherInfo.HadoopUrl = "http://192.168.1.110:50070"
    hdfs.HadoopOtherInfo.HadoopVersion = "v2.7.0"

    fmt.Println(hdfs)
    fmt.Println(*hdfs)
    fmt.Println("HadoopClusterName:\t", hdfs.HadoopClusterName)
    fmt.Println("HadoopClusterNum:\t", hdfs.HadoopClusterNum)
    fmt.Println("HadoopClusterVersion:\t", hdfs.HadoopOtherInfo.HadoopVersion)
    fmt.Println("HadoopClusterUrl:\t", hdfs.HadoopOtherInfo.HadoopUrl)

}

匿名字段

//匿名字段  测试
package main

import "fmt"

type students struct {
    //这些就是匿名字段,没有定义名字
    string
    int
}

func main() {
    boy := &students{
        //初始化的时候,必须按照顺序来进行的
        "xiaoqiang", 19}
    fmt.Println(boy)
}

相同结构体 之间 操作,如赋值,比较

// 相同结构体  之间 操作,如赋值,比较
package main

import "fmt"

type teacherA struct {
    string
    int
}
 type teacherB struct {
    string
    int
 }

func main() {

    boyTeacherA := teacherA{"xiaoli",22}
    //boyTeacherB := teacherB{"xiaoli",22}
    //説明:编译报错了,teacherA, teacherB  类型不相同,不能进行比较的
    //fmt.Println(boyTeacherA == boyTeacherB)

    boyTeacherB := teacherA{"xiaoli", 23}
    fmt.Println(boyTeacherB == boyTeacherA)

}

结构体,实现 类似于 继承的效果

//结构体,实现 类似于 继承的效果
package main

import "fmt"

type anminal struct {
    //设置一些共有的属性
    Name, address string
}

type cat struct {
    //anminal  Go 语言,默认,anminal是类型,同时也是属性名称
    anminal
    Sex int         // 猫的特有属性,性别是啥
}

type dog struct {
    anminal
    Hobby string  //狗的特有属性,爱好
}

func main() {
    //第一种初始化方式
    xiaoCat := cat{Sex:0, anminal : anminal{Name:"xiaohong", address:"beijing"}}
    xiaoDog := dog{Hobby:"play", anminal:anminal{Name:"xiaohuang", address:"shanghai"}}

    //第二种初始化方式
    xiaoCat.anminal.Name = "xiaoxiaoxiaohong" //这种方式,是为了防止名字相同时,冲突
    xiaoCat.Name = "xiaoxiaohong"

    fmt.Println("cat:\t", xiaoCat)
    fmt.Println("dog:\t",xiaoDog)

}

原文地址:http://blog.51cto.com/xingej/2103044

时间: 2024-08-28 16:27:39

Go 语言之 struct 结构体的相关文章

c语言 struct结构体的变量声明加冒号

有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可. 为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为"位域"或"位段".所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作.这样就可以把几个不同的对象用一个字节的二进制位域来表示. [1]定义: struct 位域结构名 { 位

黑马程序员 C语言-枚举,结构体,指针

一.枚举 ※枚举变量的定义 前面只是定义了枚举类型,接下来就可以利用定义好的枚举类型定义变量. 跟结构体一样,有3种方式定义枚举变量 1.先定义枚举类型,再定义枚举变量 enum Season {spring, summer, autumn, winter}; enum Season s; 2.定义枚举类型的同时定义枚举变量 enum Season {spring, summer, autumn, winter} s; 3.省略枚举名称,直接定义枚举变量 enum {spring, summer

go struct结构体

struct结构体 用来自定义复杂数据结构 struct里面可以包含多个字段(属性) struct类型可以定义方法,注意和函数的区分 struct类型是值类型 struct类型可以嵌套 Go语言没有class类型,只有struct类型 1.struct 声明 type 标识符 struct { field1 type field2 type } 样例: type Student struct { Name string Age int Score int } 2.struct 中字段访问:和其他

struct结构体详解

为什么要有结构体 结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成你想要的数据类型.以方便日后的使用. 在实际项目中,结构体是大量存在的.研发人员常使用结构体来封装一些属性来组成新的类型.由于C语言内部程序比较简单,研发人员通常使用结构体创造新的"属性",其目的是简化运算. 结构体在函数中的作用不是简便,其最主要的作用就是封装.封装的好处就是可以再次利用.让使用者不必关心这个是什么,只要根据定义使用就可以了. 在C语言中,可以定义结构体类型,将多个相

关于c语言中的结构体使用偏移量求值问题

最近在看nginx源码,看到定时器的时候,发现一个结构体利用偏移量求值问题, 结构体相信做c开发的都遇到过,那么不知你对结构体中成员变量偏移这块是如何理解的; 首先我们先看一下nginx中的那个让我迷惑的地方 ev =    (event_t*)((char*)node - offsetof(event_t, timer)); 这里,可以得知道是利用event_t结构体的timer变量,来反求event_t结构体的地址 说明一下: event_t是一个结构体 node 也是一个结构体 timer

C语言中的结构体,结构体数组

C语言中的结构体是一个小难点,下面我们详细来讲一下:至于什么是结构体,结构体为什么会产生,我就不说了,原因很简单,但是要注意到是结构体也是连续存储的,但要注意的是结构体里面类型各异,所以必然会产生内存对齐的问题.也就是内存里面会有空档. 1.结构体的定义和赋值 结构体是可以直接初始化的,在定义的时候,就可以初始化,而且如果你的结构体中恰好有字符数组的话,这个时候初始化是不错的选择,原因很简单,字符数组只能定义的时候直接初始化 后来就不可以了,后来你就只能用strcpy函数来拷贝初始化了. str

浅谈c语言typedef 与结构体指针(个人小经验)

 #include<stdio.h> #include<string.h> typedef struct emp{ char sex[8]; char name[15]; int age; }*emp;//这里我们用typedef把emp这个结构体变成了*emp这种指向结构体成员的结构体指针 /*typedef struct emp{ char sex[8]; char name[15]; int age; }pi,*emp;//为了程序的可读性最好不要这样声明*/ int m

linux 中 C 语言的使用 -- 结构体多态

在 Linux 内核代码,特别是驱动代码中经常见到的用法是使用一个标准结构,后面的代码基于这个结构来实现,类似面向对象的多态特性. 在 C 语言里面借助结构体和函数指针实现的这个功能,这里我们写了个例子,提取了关键代码: #include <stdio.h> struct s_new{ char name[10]; char* (* my_method)(char *name); }; char* powerful(char *name){ printf("%s is powerfu

9.Go语言基础之结构体

Go语言中没有类的概念,也不支持"类"的继承等面向对象的概念. Go语言中通过结构体的内嵌再配合接口,比面向对象具有更高的扩展性和灵活性. 1.类型别名和自定义类型 1.1自定义类型 在Go语言中有一些基本的数据类型,如string,整型,浮点型,布尔等数据类型,Go语言中可以使用type关键字来定义自定义类型. 自定义类型是定义了一个全新的类型.我们可以基于内置的基本类型定义,也可以通过struct定义. //将MyInt定义为int类型 type MyInt int 通过Type关