golang 碎片整理之 结构体

什么是结构体?

结构体(struct)是用户自定义的类型,它代表若干字段的集合,可以用于描述一个实体对象,类似Java中的class,是golang面向对象编程的基础。
结构体的概念在软件工程上的旧术语是ADT(抽象数据类型: Abstract Date type)。在c++它也是存在,并且名字也是struct,在面向对象的编程语言中,跟一个无方法的轻量级类一样。因为在Go语言中没有类的概念,所以在go中结构体有着很重要的地位。

如何定义一个结构体

type Coordinate struct {
    X,Y float32
}

上述代码定义了一个名为Coordinate的结构体,里面包括了两个float32的变量X,Y。该结构体可用于描述一个平面坐标。

添加对象方法

在go语言中,对象方法在结构体定义的外部添加

type Coordinate struct {
    X,Y float32
}
func (coo *Coordinate) GetCoordinate() {
    fmt.Printf("(%.2f, %.2f)\n", coo.X, coo.Y)
        return
}

其中,func关键字后面的(coo *Coordinate),表示该函数传入一个指向Coordinate的指针,可通过指针变量coo来操作结构体的值。

几种结构体的初始化

  1. 按照原始字段顺序通过创建结构体

    package main
    import (
    "fmt"
    )
    func main(){
    p0 := Coordinate{1,2}
    p0.GetCoordinate()
    }

    输出:(1.00, 2.00),其中X=1,Y=2

2.按照自定义字段顺序进行初始化

package main
import (
    "fmt"
)
func main(){
    p0 := Coordinate{Y:1, X:2}
    p0.GetCoordinate()
}

输出:(2.00,1.00),其中X=2,Y=1

3.通过new函数创建

package main
import (
                "fmt"
)
func main(){
                p0 := new(Coordinate)
                P0.X=1
                p0.Y=2
                p0.GetCoordinate()
}

其中p0 := new(Coordinate)等价于以下写法
p3 := &Coordinate{X:1,Y:2}
p3 := &Coordinate{1,2}
比较三种创建方式,其中,第一种和第二种,p0均为一个类型为Coordinate的实例,而第三种p0为一个指向Coordinate的指针,相当于 var p0 *Coordinate = new(Coordinate)

添加值拷贝的对象方法

刚才说了,添加一个对象方法,可以通过func (t *T) functionname() 来创建,其中t是一个指针变量。我们也可以通过值拷贝的方法,添加一个对象方法,语法为 func(t T) functionname()

package main
import (
    "fmt"
)
type Coordinate struct {
    X, Y float32
}

func (coo *Coordinate) GetCoordinate() {
    fmt.Printf("(%.2f,%.2f)\n", coo.X, coo.Y)
    return
}
//值拷贝对象方法
func (coo Coordinate) SetPosition01(a float32,b float32) {
    coo.X = a
    coo.Y = b
}

//指针变量对象方法
func (coo *Coordinate) SetPosition02(a float32,b float32) {
    coo.X = a
    coo.Y = b
}
func main(){
    p0 := Coordinate{1, 2}
    fmt.Print("SetPosition02调用前:")
    p0.GetCoordinate()
    p0.SetPosition02(0, 0)
    fmt.Print("SetPosition02调用后:")
    p0.GetCoordinate()
}

输出:
SetPosition01调用前:(1.00,2.00)
SetPosition01调用后:(1.00,2.00)
SetPosition02调用前:(1.00,2.00)
SetPosition02调用后:(0.00,0.00)

从程序输出中可以看出,调用SetPosition01方法,发生了值拷贝,即使在方法内改变了coo的值,外部的p0的值没有被改变。而SetPosition02方法中,coo为指向p0地址的指针,由于是通过指针变量修改了X,Y的值,所以调用完毕后,外部p0的值会被修改为(0,0)

匿名结构体

package main
import (
    "fmt"
)
func main(){
    p_3d := struct {
            X,Y,Z float32
        }{1,2,3}
        fmt.Println("------输出p_3d--------")
        fmt.Printf("%v\n%T\n",p_3d, p_3d)
}

输出为:

-------输出p_3d-------
{1 2 3}
struct { X float32; Y float32; Z float32 }

golang构造函数

Go语言的结构体没有构造函数,我们可以自己实现。 例如,下方的代码就实现了一个person的构造函数。 因为struct是值类型,如果结构体比较复杂的话,值拷贝性能开销会比较大,所以该构造函数返回的是结构体指针类型。

func newPerson(name, city string, age int8) *person {
    return &person{
        name: name,
        city: city,
        age:  age,
    }
}

调用构造函数
p9 := newPerson("张三", "沙河", 90)
fmt.Printf("%#v\n", p9) //&main.person{name:"张三", city:"沙河", age:90}

原文地址:https://blog.51cto.com/13766835/2388863

时间: 2024-10-15 17:55:10

golang 碎片整理之 结构体的相关文章

在Golang里如何实现结构体成员指针到结构体自身指针的转换

原文地址:http://goworldgs.com/?p=37 在C语言中有一个经典的宏定义,可以将结构体struct内部的某个成员的指针转化为结构体自身的指针.下面是一个例子,通过FIELD_OFFSET宏计算结构体内一个字段的偏移,函数getT可以从一个F*的指针获得对应的T*对象. struct F { int c; int d; } struct T{ int a; int b; struct F f; } #define FIELD_OFFSET(type, field) ((int)

golang 使用reflect反射结构体

"反射结构体"是指在程序执行时,遍历结构体中的字段以及方法. 1.反射结构体 下面使用一个简单的例子说明如何反射结构体. 定义一个结构体,包括3个字段,以及一个方法. 通过reflect包,首先查看这个结构体对应的动态类型reflect.Type和动态值reflect.Value,并查看这个结构体对应的基本类型. 接着查看结构体的字段数量,并遍历每个字段. 打印每个字段的类型.值.以及tag标签. 最后,调用结构体中的方法,并打印返回结果. 具体代码如下. package main i

p/invoke碎片,对结构体的处理

结构体的一些相关知识 可直接转换类类型,比如int类型,在托管代码和非托管代码中占据内存大小 和意义都是一个样的. 结构体封送的关键是:在托管代码和非托管代码中定义的一致性.什么是定义的一致性?包括结构体的对齐粒度:结构体成员的顺序和每个结构体成员在托管代码和非托管代码中的占据内存的大小.本来想着是只是类型一样就行了,但是像布尔类型,在托管代码中占据1个字节,但是在非托管代码中是4个字节,也就是非可直接转换类型. 对齐粒度.这个东西感觉和内存布局有关,以前有一个错误的理念:在一个结构体中定义了一

12、C#基础整理(结构体)

结构体 1.概念: 结构体是写在main函数外的数据结构,由不同类型的数据组合成一个整体,这些组合在一个整体中的数据是互相联系的 2.声明方式: struct 结构体名 { 成员变量(由类型名+成员名组成) } 例: public struct student//public是修饰符,可以不加,作用范围为整个命名空间 { public int Code;//定义变量,每一个变量叫做结构体的属性 public string Name; public string Sex; public int A

C#整理8——结构体

结构体:相当于是我们自己定义的一种复杂的类型.int... double float bool char string DateTime 数组类型生活中大部份的对象都是复合型的对象. 如何定义结构体类型?一般来说结构体的定义要放在class的外面或class的里面,尽量不放在Main的里面.struct 自定义类型名{public 变量类型 变量名;......;......;......; }例如:struct YuanGong //自定义的数据类型.用来描述员工的信息.{public str

golang 兼容不同json结构体解析实践

线上服务器,同一个web接口有时需要兼容不同版本的结构体.这种情况思路是使用interface{}接收任意类型数据,结合reflect包处理. 如下,http接口调用者会传入不同的json结构数据(单体结构或切片结构): type ReqStu struct { XXX struct { //XXX结构为单体 AAA string `json:"aaa"` BBB string `json:"bbb"` CCC string `json:"ccc"

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

基本上到这里的时候,就是上了一个台阶了.Go的精华特点即将展开. 结构体定义 上面我们说过Go的指针和C的不同,结构体也是一样的.Go是一门删繁就简的语言,一切令人困惑的特性都必须去掉. 简单来讲,Go提供的结构体就是把使用各种数据类型定义的不同变量组合起来的高级数据类型.闲话不多说,看例子: type Rect struct { width float64 length float64 } 上面我们定义了一个矩形结构体,首先是关键是type表示要定义一个新的数据类型了,然后是新的数据类型名称R

golang碎片整理之反射

本文介绍go语言反射的意义和基本使用. 变量的内在机制 go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息 值信息:程序运行过程中可动态变化的. 反射的介绍 反射是指在程序运行期对程序本身进行访问和修改的能力.程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分.在运行程序时,程序无法获取自身的信息.支持反射的语言可以在程序编译期将变量的反射信息,如字段名称,类型信息.结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射

golang 碎片整理之 并发

并发与并行 并发:同一时间段内执行多个任务.并行:同一时刻执行多个任务. Go语言的并发通过goroutine实现.goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作.goroutine是由go语言的运行调度完成的,而线程是由操作系统调度完成的.Go语言还提供了channel在多个goroutine间进行通信.goroutine和channel是go语言秉承的CSP(Communicating Sequential Process)并发模式的