struct结构体

  • 用来自定义复杂数据结构
  • struct里面可以包含多个字段(属性),字段可以是任意类型
  • struct类型可以定义方法,注意和函数的区分
  • struct类型是值类型
  • struct类型可以嵌套
  • Go语言没有class类型,只有struct类型

make 用来创建map、slice、channel

new用来创建值类型

1、struct 声明

type 标识符 struct {
field1 type
field2 type
}

样例:

type Student struct {
Name string
Age int
Score int
}

2、struct 中字段访问:和其他语言一样,使用点

var stu Student

stu.Name = “tony”
stu.Age = 18
stu.Score=20 fmt.Printf(“name=%s age=%d score=%d”, stu.Name, stu.Age, stu.Score)

3、struct定义的几种形式:

  • a. var stu Student  //值类型
  • b. var stu *Student = new(Student)  //引用类型
  • c. var stu *Student = &Student{}  //引用类型
  • d. var stu Student = Student {}  //值类型

备注:其中b和c返回的都是指向结构体的指针,访问形式如下:

stu.Name、stu.Age和stu.Score或者 (*stu).Name、(*stu).Age等

可以理解为语法糖,写stu.Name时底层会转成(*stu).Name

4. struct的内存布局:struct中的所有字段在内存是连续的,布局如下:

type Rect1 struct { Min, Max Point }

type Rect2 struct { Min, Max *Point }

package main

import (
"fmt"
) type Point struct {
x int
y int
} type Rect1 struct {
p1 Point
p2 Point
} type Rect2 struct {
p1 *Point
p2 *Point
} func main() {
var r1 Rect1
var r2 Rect2 r2.p1 = new(Point)
var r3 = new(Point)
var r4 = new(Point)
r2.p2 = new(Point) fmt.Println(r3, r4)
//r1的内存布局
fmt.Printf("p1.x addr:%p\n", &r1.p1.x)
fmt.Printf("p1.y addr:%p\n", &r1.p1.y)
fmt.Printf("p2.x addr:%p\n", &r1.p2.x)
fmt.Printf("p2.y addr:%p\n", &r1.p2.y)
fmt.Println()
fmt.Println()
//r2的内存布局
fmt.Printf("p1.x addr:%p\n", &(r2.p1.x))
fmt.Printf("p1.y addr:%p\n", &(r2.p1.y))
fmt.Printf("p2.x addr:%p\n", &(r2.p2.x))
fmt.Printf("p2.y addr:%p\n", &(r2.p2.y))
fmt.Printf("p1:%p\n", &r2.p1)
fmt.Printf("P2:%p\n", &r2.p2)
}

5、链表定义

每个节点包含下一个节点的地址,这样把所有的节点串起来了,通常把 链表中的第一个节点叫做链表头。

type Student struct {
Name string
Next* Student
}

样例一:

package main

import (
"fmt"
) type Student struct {
Name string
Age int
Score float32
next *Student
} func main() {
var head Student
head.Name = "hua"
head.Age = 18
head.Score = 100 var stu1 Student
stu1.Name = "stu1"
stu1.Age = 23
stu1.Score = 23 head.next = &stu1
var p *Student = &head
for p != nil {
fmt.Println(*p)
p = p.next
}
fmt.Println()
}

6、双链表定义

如果有两个指针分别指向前一个节点和后一个节点,我们叫做双链表。

type Student struct {
Name string
Next* Student
Prev* Student
}
package main

import (
"fmt"
"math/rand"
) type Student struct {
Name string
Age int
Score float32
next *Student
} func trans(p *Student) {
for p != nil {
fmt.Println(*p)
p = p.next
}
fmt.Println()
} func insertTail(p *Student) {
var tail = p
for i := 0; i < 10; i++ {
stu := Student{
Name: fmt.Sprintf("stu%d", i),
Age: rand.Intn(100),
Score: rand.Float32() * 100,
}
tail.next = &stu
tail = &stu
}
} func insertHead(p **Student) {
for i := 0; i < 10; i++ {
stu := Student{
Name: fmt.Sprintf("stu%d", i),
Age: rand.Intn(100),
Score: rand.Float32() * 100,
}
stu.next = *p
*p = &stu
}
} func addNode(p *Student, newNode *Student) { for p != nil {
if p.Name == "stu9" {
newNode.next = p.next
p.next = newNode
break
} p = p.next
}
} func main() {
var head *Student = new(Student)
head.Name = "hua"
head.Age = 18
head.Score = 100 insertTail(head)
trans(head)
insertHead(&head)
trans(head) var newNode *Student = new(Student) newNode.Name = "stu1000"
newNode.Age = 18
newNode.Score = 100
addNode(head, newNode)
trans(head)
}

7、二叉树定义

如果每个节点有两个指针分别用来指向左子树和右子树,我们把这样的 结构叫做二叉树。

type Student struct {
Name string
left* Student
right* Student
}

样例:

package main

import "fmt"

type Student struct {
Name string
Age int
Score float32
left *Student
right *Student
} func trans(root *Student) {
if root == nil {
return
}
fmt.Println(root) trans(root.left)
trans(root.right) } func main() {
var root *Student = new(Student) root.Name = "stu01"
root.Age = 18
root.Score = 100 var left1 *Student = new(Student)
left1.Name = "stu02"
left1.Age = 18
left1.Score = 100 root.left = left1 var right1 *Student = new(Student)
right1.Name = "stu04"
right1.Age = 18
right1.Score = 100 root.right = right1 var left2 *Student = new(Student)
left2.Name = "stu03"
left2.Age = 18
left2.Score = 100 left1.left = left2 trans(root)
}

8、结构体是用户单独定义的类型,不能和其他类型进行强制转换

package main

import "fmt"

type integer int

type Student struct {
Number int
} type Stu Student //alias func main() { var i integer = 1000
var j int = 100 j = int(i)
fmt.Println(j) var a Student
a = Student{30}
fmt.Println(a) var b Stu
a = Student(b)
fmt.Println(a) }

9、golang中的struct没有构造函数,一般可以使用工厂模式来解决这个问题

Package model
type student struct {
Name stirng
Age int
} func NewStudent(name string, age int) *student {
return &student{
Name:name,
Age:age,
}
} Package main
S := new(student)
S := model.NewStudent(“tony”, 20)

10、struct中的tag

我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的 机制获取到,最常用的场景就是json序列化和反序列化。

package main

import (
"encoding/json"
"fmt"
) type Student struct {
Name string `json:"student_name"`
Age int `json:"age"`
Score int `json:"score"`
} func main() {
var stu Student = Student{
Name: "stu01",
Age: 18,
Score: 80,
} data, err := json.Marshal(stu)
if err != nil {
fmt.Println("json encode stu failed, err:", err)
return
} fmt.Println(string(data))
}

11、匿名字段

结构体中字段可以没有名字,即匿名字段。

package main

import(
"fmt"
"time"
) type Car struct{
name string
age int
} type Train struct{
Car
int
start time.Time
} func main() {
var t Train
t.Car.name = "001"
t.Car.age = 100 t.name = "train"
t.age = 200 fmt.Println(t)
}

12、组合和匿名字段

如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问 匿名结构体的方法,从而实现了继承。

如果一个struct嵌套了另一个有名结构体,那么这个模式就叫组合。

13、实现String()

如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个 变量的String()进行输出。

package main

import "fmt"

type Car struct {
weight int
name string
} func (p *Car) Run() {
fmt.Println("running")
} type Bike struct {
Car
lunzi int
} type Train struct {
Car
} func (p *Train) String() string {
str := fmt.Sprintf("name=[%s] weight=[%d]", p.name, p.weight)
return str
} func main() {
var a Bike
a.weight = 100
a.name = "bike"
a.lunzi = 2 fmt.Println(a)
a.Run() var b Train
b.weight = 100
b.name = "train"
b.Run() fmt.Printf("%s", &b)
}

方法

Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以 有方法,而不仅仅是struct

定义:func (recevier type) methodName(参数列表)(返回值列表){}

方法的访问控制,通过大小写控制

package main

import "fmt"

type Student struct {
Name string
Age int
Score int
sex int
} func (p *Student) init(name string, age int, score int) {
p.Name = name
p.Age = age
p.Score = score
fmt.Println(p)
} func (p Student) get() Student {
return p
} func main() {
var stu Student
stu.init("stu", 10, 200) stu1 := stu.get()
fmt.Println(stu1)
}

继承

如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问 匿名结构体的方法,从而实现了继承。

package main

import "fmt"

type Car struct {
weight int
name string
} func (p *Car) Run() {
fmt.Println("running")
} type Bike struct {
Car
lunzi int
} type Train struct {
c Car
} func main() {
var a Bike
a.weight = 100
a.name = "bike"
a.lunzi = 2 fmt.Println(a)
a.Run() var b Train
b.c.weight = 100
b.c.name = "train"
b.c.Run()
}

多重继承

如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问 多个匿名结构体的方法,从而实现了多重继承。

package main

import (
"fmt"
) type Cart1 struct {
name string
age int
} type Cart2 struct {
name string
age int
} type Train struct {
Cart1
Cart2
} func main() {
var t Train t.Cart1.name = "train"
t.Cart1.age = 100 fmt.Println(t)
}

go struct结构体的更多相关文章

  1. C# Struct结构体里数组长度的指定

    typedef struct Point{ unsigned short x; unsigned short y; }mPoint;//点坐标 typedef struct Line{ mPoint ...

  2. C#基础--struct(结构体)

    结构体和类有点类似    我们定义一个类的时候    是class   类名   定义结构体的时候是 struct   结构体名 结构体的写法 struct Point { // public int ...

  3. 1.0 基础、标示符、常量、数据类型(enum 枚举,struct 结构体)、操作符、循环、数组

    一.程序 现实生活中,程序是指完成某些事务的一种既定方法和过程,可以把程序看成是一系列动作执行过程的描述. 在计算机世界,程序是指令,即为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集 ...

  4. C#语言struct结构体适用场景和注意事项

    在C#语言中struct结构体和class之间的区别主要是值类型和引用类型的区别,但实际上如果使用不当是非常要命的.从Win32时代过来的人对于struct一点不感觉陌生,但是却反而忽略了一些基本问题 ...

  5. C语言 Struct 结构体在 Java 中的体现

    大一整个学期完成了 C 语言的学习,大二就进入了Java 的学习. 和C语言一样,我们都会尝试写一个小小的学生管理系统什么的,学习过 C 语言同学知道,在管理系统中 Struct 结构体是个很好用的东 ...

  6. Swift Struct 结构体

    前言 Swift 语言有两种基本的数据类型,即类(class)和结构体(struct),class 这样的概念大家不会陌生,而 struct 也并不是什么新的概念,在 Objective-C 和 C ...

  7. struct 结构体解析(原)

    (一)基本概念 结构体是一个或是多个变量的集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组合在一个名字之下.我们将关键字struct引入了结构声明中.结构声明包含在花括号内的一系列声明组成 ...

  8. struct结构体在c和c++中的差别

    非常多次遇到这个struct的问题,今天在这里简单总结一下我的理解 一.struct在C 中的使用 1.单独使用struct定义结构体类型 struct Student { int id; int n ...

  9. Go - Struct 结构体

    目录 概述 声明结构体 生成 JSON 改变数据 推荐阅读 概述 结构体是将零个或多个任意类型的变量,组合在一起的聚合数据类型,也可以看做是数据的集合. 声明结构体 //demo_11.go pack ...

随机推荐

  1. [Beta阶段]展示博客

    一.团队成员简介与个人博客地址 团队博客地址:http://www.cnblogs.com/wowotoubuaa/ 江昊,项目经理http://www.cnblogs.com/haoj/ 王开,后端 ...

  2. Practice3 阅读《构建之法》1-5章

    第一章:概论 本章主要是讲了软件工程的基本概念,软件工程的最终目标是创造“足够好”的软件. 提出问题:什么是BUG?(出自1.2.5节) 答:就我个人而言,在许多游戏中也有许多的BUG,BUG这一词在 ...

  3. 使用phpstudy创建本地虚拟主机

    在使用php开发网站的时候,每次测试自己的网站时,通常都是用localhost/dirname/filename.php来访问自己所写的程序 但是有时候我们需要模拟真实的场景,如通过域名访问时,如果你 ...

  4. Win2016以及win10 IIS10 下安装IEwebcontrol的方法

    1. 公司产品需要安装IE webcontrol控件 但是在win2016以及win10 上面安装时 因为IIS 已经升级到了IIS10 安装时会提示: 兼容解决的方法比较简单,修改注册表即可 HKE ...

  5. 软件开的目录规范+sys,os,time模块

    —————————————————————————————————————————————————————————————————— start.py import sys,os # print(__ ...

  6. aliyun centos14.04 trusty 上安装docker1.12.1

    现在apt这边拿到的docker最新版本就是1.12.1 其实本来这次不准备记录了,本以为一帆风顺的安装最后还是遇到了一点坑,aliyun的锅,卡成狗无法下载.青岛机房 1.更新源,然后安装ca-ce ...

  7. rsync实现数据同步

    希望两台机器指定目录的数据保持一致 192.168.19.252(master)                 192.168.19.251(slave) /cache 拉复制            ...

  8. IBM推出新一代云计算技术来解决多云管理

    IBM 云计算论坛在南京举行,推出了一项全新的开放式技术,使用户能够更加便捷地跨不同云计算基础架构来管理.迁移和整合应用. IBM 多云管理解决方案(Multicloud Manager)控制面板 据 ...

  9. MVC 多语言

    最近项目需要用到多语言. 研究了一下,也参考了很多技术文章. 这里贴一下参考地址:http://www.cnblogs.com/unintersky/p/3969612.html 主要步骤我这里简述一 ...

  10. UVA11987 Almost Union-Find

    题目描述 PDF 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 5 7 1 1 2 2 3 4 1 3 5 3 4 2 4 1 3 4 3 3 输出样例#1: 3 12 3 7 ...