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 原类型 ...
随机推荐
- OS第1次实验报告:熟悉使用Linux命令和剖析ps命令
零.个人信息 姓名:陈韵 学号:201821121053 班级:计算1812 一.实验目的 熟悉Linux命令行操作 二.实验内容 使用man查询命令使用手册 基本命令使用 三.实验报告 1. 实验环 ...
- iOS nil,Nil,NULL,NSNULL的区别
nil (id)0 是OC对象的空指针,可正常调用方法(返回空值,false,零值等) Nil (Class)0 是OC类的空指针,主要运用于runtime中,Class c = Nil; 其他特性 ...
- python——新excel模块之openpyxl
1.安装 pip install openpyxl 2.新建文件 book=openpyxl.Workbook() 3.打开sheet页(两种方式) sheet=book.active #默认的she ...
- SQL实战(三)
一. 查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_noy以及其对应的薪水涨幅growth,并按照growth进行升序CREATE TABLE `employees` (`emp_no` ...
- MATLAB——m_map指南(1)
1.例图 (1) clear all m_proj('oblique mercator');%确定投影方式和绘图界线 m_coast;%画出海岸线 m_grid;%添加格网 第一行代码初始化投影,对于 ...
- WebView的基本使用及相关特性
WebView 是一个显示网页内容的组件,可以显示网络上的一些在线内容并且可以作为 Web 浏览器滚动显示的内容,它使用 WebKit作为渲染引擎来显示网页,里面包括放大.缩小.执行文本搜索等进行前后 ...
- 从 Socket 编程谈谈 IO 模型(三)
快过年啦,估计很多朋友已在摸鱼的路上.而我为了兄弟们年后的追逐,却在苦苦寻觅.规划,导致文章更新晚了些,各位猿粉谅解. 上期分享,我们结合新春送祝福的场景,通过一坨坨的代码让 BIO.NIO 编程过程 ...
- 【Redis】集群NetCore实战
环境准备 1. Redis集群(Windows集群搭建) 启动Redis集群,给每个节点加上Title start .conf start .conf start .conf start .conf ...
- 第一章构建vue项目,代码仓库管理
一.安装node.js.vue-cli脚手架 1.安装node.js 下载地址:https://nodejs.org/en/download 查看版本号 node -v .npm -v 出现版本号即安 ...
- python--匿名函数、文件操作
一.匿名函数 语法: sum = lambda arg1, arg2: arg1 + arg2 #调用sum函数 print "Value of total : ", sum( 1 ...