结构体简介

  Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型。一个带属性的结构体试图表示一个现实世界中的实体。结构体是复合类型(composite types),当需要定义一个类型,它由一系列属性组成,每个属性都有自己的类型和值的时候,就应该使用结构体,它把数据聚集在一起。然后可以访问这些数据,就好像它是一个独立实体的一部分。结构体也是值类型,因此可以通过 new 函数来创建。

  组成结构体类型的那些数据称为 字段(fields)。每个字段都有一个类型和一个名字;在一个结构体中,字段名字必须是唯一的。

  Go中没有类的概念

结构体定义

  • 如果字段在代码中从来不会用到,那么就可以把它命名为_(单独使用下划线,在Go中表示忽略)
  • 结构体的字段可以事任何类型,也可以是函数或是接口
 type identifier struct{
field1 type1
field2 type2
...
} // 声明
var s identifier
identifier.field1 = value
identifier.field2 = value

结构体声明

 // 下面三种相同,t为结构体指针
var t *T // T是结构体类型
t = new(T) // 结构体指针变量t var t *T = new(T) t := new(T) // 指针变量t
    不使用new的声明方式:var t T 也会给t分配内存,并零化内存,t为类型T而不是指针类型*T
 

结构体赋值和使用

    使用点符号给字段赋值或者获取结构体字段的值,变量不管是结构体类型还是结构体指针类型,都使用点符号来引用结构体的字段
 注意当变量类型是指针结构体时,既可以通过指针给结构体字段赋值,也可以通过使用解指针的方式给结构体字段赋值,注意下面的例子
 import "fmt"
type struct1 {
i1 int
f1 float32
s1 string
}
func main(){
ms := new(struct1) // ms是*struct1类型
ms.i1 = 10 // 这是通过指针给结构体字段赋值,也可以通过解指针的方式给结构体赋值 这样子(*ms).i1 = 10
ms.f1 = 1.2
ms.s1 = "hello,word"
fmt.Println(ms.i1)
fmt.Println(ms.f1)
fmt.Println(ms.s1)
}
 
 

结构体初始化

 // 方式一
ms:=&struct1{10,1.1,"gao"} // ms的类型是*struct1 // 方式二
var ms struct1
ms = struct1{10,1.1,"hu"} // ms的类型是ms
// 举例
type Interval struct{
start int
end int
}
// 以下三种初始化方式
intr := Interval{0,3}
intr := Interval{start:3,end:3}
intt := Interval{end:4}
 
 

结构体的内存分布

Go语言中,结构体和它所包含的数据在内存中是以连续块的形式存在的,即使结构体中嵌套有其他的结构体,这在性能上带来了很大的优势。
type Rect1 struct {Min, Max Point}
type Rect2 struct {Min, Max *Point} 
 
 

【结构体转换】

Go中的类型转换遵循严格的规则。当为结构体定义了一个alias类型时,此结构体类型和它的alias类型都有相同的底层类型。
 package main

 type number struct{
a int
} type aliasNumber number // 为结构体number定义了一个alias类型 aliasNumber
 
 

Go中实现构造方法

    1- 原本不存在构造方法
 type File struct {
fd int // 文件描述符
name string // 文件名
} fun newFile(fd int, name,string)*File{
if fd<0{
return nil
}
return &File{fd,name}
}
    2- 强制用户使用工厂方法:前面提到过,变量小写就会变成私有的,这里的实现也是这个原理。将结构体定义为私有的,在开放一个共有的方法来返回结构的指针。
 type matrix struct{
//
}
func NewMatrix(params)*matrix{
m := new(matrix)
return m
} // 在其他包中引入使用
package main
import "matrix"
wrong := new(matrix.matrix) // wrong way
right := matrix.NewMatrix(...) // right way
 

带标签的结构体

  结构体的字段除了有名字和类型外,还可以有一个可选的标签:它是附属于字段的字符串,可以是文档或其他的重要标记。标签的内容不可以在一般的编程中使用,只有反射包reflect能够获取它。

示例如下

 package main

 import "fmt"
import "reflect" type TagType struct{
f1 bool "an important answer"
f2 string "the name of the thing"
f3 int "how much there are"
} fun main(){
tt := TagType{true,"kobe",82}
for i:=0;i<3,i++{
refTag(tt,i)
}
}
func refTag(tt TagType,ix int){
ttType := reflect.Typeof(tt)
ixField := ttType.Field(ix)
fmt.Printf("%v\n",ixField.Tag)
}

结构体中的匿名字段

  结构体中可以包含一个或多个匿名字段(字段没有名字,只有类型,这个类型可以包括结构体类型),但是一个结构体中只能包含一种类型的匿名字段。比如不能同时包含两个int int匿名字段(结构体类型也是同样的道理)。

  使用带有匿名字段的结构体时,类型名称就是字段名,这就是为什么一个类型只能出现一次了。

package main
import "fmt"
type struct1 struct{
f1 int
f2 bool
f3 string
float32
struct2
}
type struct2 struct{
s1 string
}
func main(){
s1 := new(struct1)
s1.f1 = 1
s1.f2 = true
s1.f3 = "boom"
s1.float32 = 2.3
s1.s1 = "childern"
fmt.Println(s1)
}

结构体中出现命名冲突

  • 外层名字会覆盖内层名字(但是两者的内存空间都保留),这提供了一种重载字段或方法的方式
  • 如果相同的名字在同一级别出现了两次,如果这个名字被程序使用了,将会引发错误。

  如果想要使用内层的就通过层层去调用

 package main

 import (
"fmt"
) type A struct {
a int
}
type B struct {
a int
b int
} type C struct {
A
B
} func main() {
var c_struct C
c_struct.A.a = 10
c_struct.b = 20
c_struct.B.a =30 fmt.Println(c_struct) }
 
 
 
 

最新文章

  1. C#-WebForm-★★★ 分页展示 ★★★
  2. Building a RESTful Web Service
  3. 定长循环队列C语言实现
  4. fir.im Weekly - 600个 Android 开源项目汇总
  5. PRML读书会第八章 Graphical Models(贝叶斯网络,马尔科夫随机场)
  6. SQl语句学习笔记(二)
  7. jdbcTemplate 泛型 查询
  8. Android源码分析之AsyncTask
  9. vim常用命令笔记(转载)
  10. smart pointer (auto_ptr)
  11. aix6.1 openssh安装
  12. 原生app与web app的比较
  13. JavaScript中的window对象
  14. TreeSet对非自然顺序元素的排序
  15. Python自学知识点----Day01
  16. 百度富文本ueditor使用小结
  17. Linux 配置SFTP,配置用户访问权限
  18. Jmeter的使用简介及实例
  19. TOR的十个最好的替代工具
  20. input type=&#39;number&#39;时,maxlength属性无效

热门文章

  1. volatile 与 synchronized 区别
  2. DOM解析原理示意
  3. Bootstrap中data-src无法显示图片,但是src可以
  4. phpstudy 虚拟主机域名配置注意问题
  5. 安装mysql后运行.net程序出错
  6. goDaddy SSL证书 Nginx配置全流程 (转)
  7. 详解Office 外接程序 COM Add In的LoadBehavior及其妙用
  8. dubbo源码—Service Reply
  9. mysql 查询今天,昨天,上个月sql语句 注解
  10. npm install安装时忘记--save解决方法