go 基础 结构体
结构体是类型中带有成员的复合类型。go语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性。
go语言中的类型可以被实例化,使用new和&构造类型实例的类型是类型的指针。
结构体成员是由一系列成员变量构成,成员(字段)有以下属性:
- 字段名称唯一;
- 拥有类型和值;
- 成员的类型可以是结构体,甚至是字段所在结构体的类型。
go不支持”类“的概念,也不支持"继承"面向对象的概念。
go 语言不仅认为结构体能拥有方法,且每种自定义类型也可以有自己的方法。
在函数外部定义结构体,作用域是全局的。
结构体基础
定义结构体
type 结构体名称 struct {
字段名 字段类型
...
}
- 结构体类型名在包内不能重复
示例,表示直角坐标系中的点的坐标
type Point struct {
X int
Y int
}
实例化结构体--为结构体分配内存并初始化
结构体定义只是一种内存布局的描述,只有结构化后才能真正分配内存。
基本的实例化形式
示例,表示直角坐标系中的点的坐标
type Point struct {
X int
Y int
}
var p Point
p.x = 10
p.y = 20
创建指针类型的结构体
使用new关键字对类型进行实例化,会形成指针类型的结构体。
type Player struct {
Name string
HealthPoint int
MagicPoint int
}
tank := new(Player)
tank.name = "Canon"
tank.HealthPoint = 300
go 语言中访问成员变量可以继续使用”.“,go增加了语法糖,将
ins.Name
转化为(*ins).Name
。
取结构体地址实例化
对结构体进行&
取地址,视为对该类型进行一次new
实例化操作。
ins := &T{}
- T表示结构体类型
- Ins 为结构体实例,类型是
*T
示例,定义一个命令行指令,指令包含名臣,关联变量和注释
type Command struct {
Name string
Var *int // 此处使用指针,可以随时与绑定的值保持同步
Comment string
}
var version int = 1
cmd := &Command{}
cmd.Name = "version"
cmd.Var = &version
cmd.Comment = "show version"
初始化结构体成员变量
使用基本形式初始化结构体
示例,颜色的RGB值
type Color struct {
R, G, B byte
}
使用键值对初始化结构体
示例,描述家庭任务关联
type People struct {
name string
child *People
}
relationship := &People{
name: "grand father",
child: &People{
name: "Dad",
child: &People{
name: "I",
},
},
}
fmt.Println(relationship.child.child.name)
使用多个值列表初始化结构体
注意
- 必须初始化结构体的所有字段
- 初始值与字段顺序保持一致
- 键值对与值列表的形式不能混用
示例,地址
type Address struct {
Privince string
City string
ZipCode int
PhoneNumber string
}
addr := Address{
"上海",
"上海",
"222300",
"0"
}
构造函数--结构体初始化的函数封装
go语言或者结构体没有构造函数的功能,结构体的初始化的过程可以用函数封装实现。
模拟构造函数重载
示例,根据颜色和名称可以构造不同猫的实例。
type Cat struct {
Name string
COlor string
}
func NewCatByName(name string) *Cat {
return &Cat{
Name: name,
}
}
func NewCatByColor(color string) *Cat {
return &Cat{
Color: color,
}
}
模拟父级构造调用
示例,黑猫是一种猫,猫是黑猫的泛称。
package main
import "fmt"
type Cat struct {
Name string
Color string
}
type BlackCat struct {
Cat // 嵌入Cat,类似于派生
}
func NewCat(name string) *Cat {
return &Cat{
Name: name,
}
}
func NewBlackCat(name string) *BlackCat {
cat := &BlackCat{}
cat.Color = "black"
cat.Name = name
return cat
}
func main() {
cat := NewCat("wow")
fmt.Println(cat)
blackcat := NewBlackCat("hello")
fmt.Println(blackcat)
}
方法
使用背包作为"对象",将物品放入背包的过程称为”方法“。
面向过程的实现方法
面向过程中没有“方法”概念,只能通过结构体和函数,由使用者用函数参数和调用关系来形成接近”方法“的概念。
package main
import "fmt"
type Bag struct {
items []int
}
func Insert(b *Bag, itemid int) {
b.items = append(b.items, itemid)
}
func main() {
bag := &Bag{}
Insert(bag, 100)
fmt.Println(bag.items)
}
Go 语言结构体方法
将背包及放入背包物品中使用go语言的结构体和方法方式编写,为 *Bag
创建一个方法。
package main
import "fmt"
type Bag struct {
items []int
}
func (b *Bag) Insert(itemid int) {
b.items = append(b.items, itemid)
}
func main() {
bag := &Bag{}
bag.Insert(100)
fmt.Println(bag.items)
}
Insert(itemid int)
的写法与函数一致,(b *Bag)
表示接收器,即Insert
作用的对象实例。每个方法只能有一个接收器。
接收器--方法作用的目标
func (接收器变量 接收器类型) 方法名(参数列表) (返回参数) {}
指针和非指针接收器的使用
在计算机中,小对象由于值复制时的速度较快,适合使用非针接收器。大对象因为复制性能较低,适合使用指针接收器,在接收器和参数间传递 不进行复制, 只是传指针。
指针类型接收器
指针类型接收器由一个结构体指针组成,更接近于面向对象中的this
和self
。
由于指针的特性,调用方法时,修改接收器成员变量,在方法结束后是有效的。
package main
import "fmt"
type Property struct {
value int
}
func (p *Property) SetValue(value int) {
p.value = value
}
func (p *Property) Value() int {
return p.value
}
func main() {
p := &Property{}
p.SetValue(1)
fmt.Println(p.Value())
}
非指针类型接收器
当方法作用于非指针接收器时,go语言会在代码运行时将接收器的值复制一份。在非指针接收器的方法中可以获取接收器的成员值,但修改后无效。
package main
import "fmt"
type Point struct {
X int
Y int
}
func (p Point) Add(other Point) Point {
return Point{p.X+other.X, p.Y+other.Y}
}
func main() {
p1 := Point{1, 1}
p2 := Point{3, 4}
fmt.Println(p1.Add(p2))
}
示例,time时间的中的Second属性是 Duration
,Duration拥有String()方法。
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Second.String())
}
//const (
// Nanosecond Duration = 1
// Microsecond = 1000 * Nanosecond
// Millisecond = 1000 * Microsecond
// Second = 1000 * Millisecond
// Minute = 60 * Second
// Hour = 60 * Minute
//)
//
//func (d Duration) String() string {
// ...
// return string(buf[w:])
结构体内嵌
结构体允许其成员字段在声明时没有宇段名而只有类型,这种形式的字段被称为类型内嵌。
type Data struct {
int
float32
bool
}
ins : = &Data{
int: 1 0,
float32 : 3 .14,
bool: true
}
结构体类型内嵌比普通类型内嵌的概念复杂 ,下面通过一个实例来理解。
package main
import "fmt"
type BasicColor struct {
R, G, B float32
}
type Color struct {
Basic BasicColor
Alpha float32
}
func main() {
var color Color
color.Basic.R = 1
color.Basic.G = 1
color.Basic.B = 0
color.Alpha = 1
fmt.Printf("%+v", color)
}
将 BasicColor 结构体嵌入Color 结构体中, BasicColor 没有宇段名而只有类型,这种写法就叫做结构体内嵌。
package main
import "fmt"
type BasicColor struct {
R, G, B float32
}
type Color struct {
BasicColor
Alpha float32
}
func main() {
var color Color
color.R = 1
color.G = 1
color.B = 0
color.Alpha = 1
fmt.Printf("%+v", color)
}
初始化结构体内嵌
package main
import "fmt"
type Wheel struct {
Size int
}
type Engine struct {
Power int
Type string
}
type Car struct {
Wheel
Engine
}
func main() {
car := Car{
Wheel: Wheel{
Size: 10,
},
Engine: Engine{
Power: 10,
Type: "Dz",
},
}
fmt.Printf("%+v", car)
}
使用匿名结构体分离json数据
package main
import (
"encoding/json"
"fmt"
)
// 定义屏幕
type Screen struct {
Size float32 // 屏幕尺寸
ResX, ResY int //屏幕水平和垂直分辨率
}
// 定义电池
type Battery struct {
Capacity int // 容量
}
func genJsonData () []byte {
raw := &struct {
Screen
Battery
HasTouchID bool
}{
Screen: Screen{
Size: 5.5,
ResX: 1920,
ResY: 1080,
},
Battery: Battery{
Capacity: 100,
},
HasTouchID: true,
}
jsonData, err := json.Marshal(raw)
if err != nil {
return make([]byte, 0)
} else {
return jsonData
}
}
func main() {
// 生成一段 JSON 数据
jsonData := genJsonData()
fmt.Println(string(jsonData))
// 只需要屏幕和指纹识别信息的结构和实例
screenAndTouch := struct {
Screen
HasTouchID bool
}{}
// 反序列化到 screenAndTouch
err := json.Unmarshal(jsonData, &screenAndTouch)
if err == nil {
fmt.Printf("%+v\n", screenAndTouch)
}
// 只需要电池和指纹识别信息的结构和实例
batteryAndTouch := struct {
Battery
HasTouchID bool
}{}
err = json.Unmarshal(jsonData, &batteryAndTouch)
if err == nil {
fmt.Printf("%+v\n", &batteryAndTouch)
}
}
go 基础 结构体的更多相关文章
- C#语言基础——结构体和枚举类型
结构体和枚举类型 一.结构体(struct) 结构类型是用户自己定义的一种类型,它是由其他类型组合而成的,可包含构造函数.常数.字段.方法.属性.索引器.运算符.事件和嵌套类型的值类型.结构在几个重要 ...
- C#基础——结构体
集合:数组:同一类型,固定长度集合:不同类型,不固定长度 要使用集合,必须先引用命名空间:using System.Collections; 定义:ArrayList arr = new ArrayL ...
- OC基础--结构体 枚举做类成员属性
结构体 枚举作类的成员属性: 定义一个学生类 性别 -- 枚举 生日 入学日期 毕业日期 -- 结构体 代码示例: 声明文件 Student.h: #import <Foundation ...
- C基础--结构体
C语言,结构体语法: 1.定义结构体类型: struct 结构体名称 { 成员类型 成员名称1; 成员类型 成员名称2; ... }; 例:struct Date { int year ; int m ...
- C基础--结构体成员初始化方式
之前在linux内核代码中看到结构体成员成员初始化使用类似于.owner = THIS_MODULE, 不太见过,于是搜了个博客,分享下: 转自:http://www.cnblogs.com/Anke ...
- C语言基础--结构体对齐,位域,联合体
结构体对齐 1--结构体对齐的原因与意义 许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值K(通常是2,4,8)的倍数,而这个k则被称为该数据类型的对齐模数 ...
- 2017-3-2 C#基础 结构体
1. 结构体:用户自定义类型定义位置:定义在Main函数的外面,类的里面 定义格式:struct 自定义名字{ public 数据类型 名字; public 数据类型 名字; ... ...} 声明实 ...
- 数据结构基础——结构体struct及类型别名typedef的使用
一.结构体的创建 在C语言中,实现数据结构的一种常用方法便是使用结构体(structure)其示例代码如下: struct stu { int num; char ch; }; struct表示创建结 ...
- C语言基础:结构体 分类: iOS学习 c语言基础 2015-06-10 21:47 28人阅读 评论(0) 收藏
结构体:是一种用户自定义的数据类型 结构体定义 struct 结构体名 { 成员类型1 成员变量名1; 成员类型2 成员变量名2; -. }; typedef 原类型 ...
随机推荐
- TensorFlow系列专题(九):常用RNN网络结构及依赖优化问题
欢迎大家关注我们的网站和系列教程:http://panchuang.net/ ,学习更多的机器学习.深度学习的知识! 目录: 常用的循环神经网络结构 多层循环神经网络 双向循环神经网络 递归神经网络 ...
- Jmeter接口测试之案例实战(十一)
在前面的知识体系中详细的介绍了Jmeter测试工具在接口自动化测试中的基础知识,那么今天更新的文章主要是对昨晚的上课内容做个总结. 首先来看Jmeter测试工具在图片上传中的案例应用.首先结合互联网产 ...
- coding++:事务管理 隔离级别
在声明事务时,只需要通过value属性指定配置的事务管理器名即可,例如:@Transactional(value="transactionManagerPrimary"). 除了指 ...
- [vijos1144]小胖守皇宫<树形dp>
题目链接:https://vijos.org/p/1144 woc我竟然A了,这道经典的树形dp或者说是树形dp的入门题我终于过了,虽然之前做过一些树形dp的题,但是这题开始还是一脸懵逼,dp方程如何 ...
- MATLAB 排序、拟合
一.数据排序整合 1.随机生成的数,从小到大排序 clear rand('seed',1)%设置随机种子,确保随机数一样 edge_range=unifrnd (1, 10, 1, 10) edge_ ...
- 360网络安全学习笔记——SQLmap
SQLmap简介 SQLmap是一个开源的自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞. SQL注入模式 1.基于布尔的盲注 2.基于时间的盲注 3.基于报错注入 ...
- [原创] 关于步科eview人机界面HMI的使用 - HMI做Slave - Modbus RS485通讯
做测试设备,或者自动化设备常常用到HMI 触摸屏 我有个案子用到了 步科的eview 触摸屏 型号 ET070 我的是单片机主板 控制 HMI显示,通讯用485 MODBUS 单片机板充当 主控 , ...
- python中的两个高阶函数map()和reduce()
1.map()传入的有两个参数,函数和可迭代对象(Itreable),map()是把传入的函数依次作用于序列的每个元素,结果返回的是一个新的可迭代对象(Iterable). map()代码如下: # ...
- .NET Core项目部署到Linux(Centos7)(八)为.NET Core项目创建Supervisor进程守护监控
目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...
- php--php设计模式留存
装饰者模式 <?php interface Decorator { public function display(); } class XiaoFang implements Decorato ...