Go语言的数据类型

1 概述

Go语言作为类C语言,支持常规的基础数据类型的的同时,支持常用的高级数据类型。他们是:

  • 整数,int,uint,int8,uint8,int16,uint16,int32,uint32,int64,uint64
  • 浮点(小数),float32,float64
  • 复数,complex
  • 字符,byte,rune
  • 字符串,string
  • 布尔,bool
  • 指针,pointor
  • 数组,array
  • nil
  • 切片,slice。(引用类型)
  • 映射,map
  • 结构体,struct
  • 接口,interface
  • 函数,func()

本篇相当于一个类型索引。包含了Go语言中的全部类型。具体每种类型的操作,请参见具体章节!

2 整数,int

支持的整型分类很细,主要差异是占用的存储空间不同。基于有无符号列出为:
有符号的:int,int8,int16,int32,int64
无符号的:uint,uint8,uint16,uint32,uint64

其中int, unit是基于处理器架构的。意味着会根据处理器来确定是32bit还是64bit。
使用时,常常使用int。或者使用int32保证兼容。
在类型推导时,推导的整型为int,其他长度整型需要在定义变量时强制声明。
示例:

42
1024
-36

整型的默认值为0。

3 浮点数,float

支持IEEE-754标准浮点数。支持32bit和64bit的浮点数float32和float64。
在类型推导时,推导的浮点型为float64。float32需要在定义变量时强制声明。
示例:

1.0
3.14
0.618
4.2E10 // 4.2*10^10

浮点数的默认值为0。

4 复数,complex32,complex64

原生支持复数。
支持32bit+32bit复数complex64,和64bit+64bit的复数complex128。

5 字符,byte,rune

使用单引号定义字符型数据,字符指的是单个字符。有两种byte和rune:
byte:单字节字符,是uint8的别名。用于存储ASCII字符集字符
rune:多字节字符,是int32的别名。用于存储unicode字符集字符。
在类型推导时,推导的字符型为rune。byte需要在定义变量时强制声明。
示例:

'c'
'康'

字符的默认值是0。字符的本质就是整数型,根据字符集得到对应的字符。

6 字符串,string

原生支持字符串。使用双引号("")或反引号(``)定义,内部是utf-8编码。
双引号:"", 用于单行字符串。
反引号:``,用于定义多行字符串,内部会原样解析。
示例:

// 单行
"心有猛虎,细嗅蔷薇"
// 多行
`
大风歌
大风起兮云飞扬。
威加海内兮归故乡。
安得猛士兮守四方!
`

字符串支持转义字符,列表如下:

  • \r 回车符(返回行首)
  • \n 换行符(直接跳到下一行的同列位置)
  • \t 制表符
  • ' 单引号
  • " 双引号
  • \\ 反斜杠
  • \uXXXX Unicode字符码值转义

7 布尔型,bool

布尔型的值只可以是常量 true 或者 false。
示例:

var (
  isFinished = false
  )

8 指针,pointer

指针类型用于存储变量地址。使用运算符 & , *完成操作。
使用运算符 p:=&v 可以获取v变量的地址。p中的数据格式类似0xc0000b9528,是一个内存地址的16进制表示。
使用运算符 *p 可以获取指针p指向变量v的值。
如图所示:

指针

在Go语言中,指针主要用于:

  • 类型指针,对指针指向的数据进行修改。函数调用时传递参数使用指针,避免值传递拷贝额外数据。注意类型指针不能进行偏移和运算。
  • 切片,由指向起始元素的原始指针、元素数量和容量组成。
    示例:
p := 42
pv := &p
*pv ++
// p == 43

9 数组,array

数组是一段固定长度的连续内存区域。是具有相同类型数据元素序列。元素类型支持任意内置类型。
数组从声明时就确定长度,可以修改数组元素,但是数组不可修改长度。
使用 [长度]类型 进行数组的声明。
示例:

// 默认值初始化
var nums [4]int // [0 0 0 0]
// 指定初始值
var position = [4]string{"east", "south", "west", "north"}
// 自动确定长度
var position = [...]string{"east", "south", "west", "north"}

会使用类型默认值初始化元素。
数组不是引用类型,变量间为值传递。

可以使用range配合循环结构完成遍历,示例如下:

for k, v := range position {
    fmt.Println(k, v)
}
// 结果
0 east
1 south
2 west
3 north

10 nil

nil,可以理解为未初始化引用。是以下类型的默认初始值:

  • pointers -> nil
  • slices -> nil
  • maps -> nil
  • channels -> nil
  • functions -> nil
  • interfaces -> nil

11 切片,slice

切片是一个拥有相同类型元素的可变长度的序列。与数组的固定长度不同,切片也被称之为动态数组。
Go提供了4中方案定义切片:

  make ( []Type ,length, capacity )
  make ( []Type, length)
  []Type{}
  []Type{value1 , value2 , ... , valueN }

或者从数组或切片生成新切片:
slice [开始索引:结束索引]

  • slice 表示目标切片对象。
  • 开始索引和结束索引对应目标切片的索引。
  • 不包含结束索引对应的元素
  • 缺省开始索引,表示从头到结束索引。
  • 缺省结束索引,表示从开始索引到末尾。
  • 两者同时缺省时,全部切取,与切片本身等效。
  • 两者同时为0时,等效于空切片,一般用于切片复位。
  var arr = [4]string{"a", "b", "c", "d"}
  var sli = arr[1:3] // ["b", "c"]

以从数组创建切片为例,理解切片,定义语法如上所示,下图为slice:

slice示意

切片的实现是由一个底层数组以及其上面的动态位置,尺寸来实现。由内部由指向起始元素的指针、元素数量length和容量capacity组成。其中:

  • 指针ptr,用于指向切片在底层数组的起始位置。
  • 尺寸len,用于记录切片内元素数量。
  • 容量cap,当前切片最大容量,也就是底层数组的容量。可以动态分配。

切片为引用类型。
切片的默认初始值为nil。
切片支持: len()尺寸, cap()容量, append()追加元素等操作。详见切片的使用。

12 映射,map

Go语言中的键值对(key->value)集合,称之为映射map。
创建语法:
var m = map[key_type]value_type{key1: value1, key2: value2}
var m = make(map[key_type]value_type)
示例,字符串型下标,字符串型值:

var m = make(map[string]string) //make()会分配内存空间,初始化。
m["east"] = "东"
m["west"] = "西"
fmt.Println(m["east"]) // 东
fmt.Println(m["west"]) // 西

// map演示
var m = map[string]string{"east": "东", "west": "西"}

支持遍历操作,使用range:

for k, v := range mapVar {
    fmt.Println(k, v)
}

映射是引用类型。
详见切片操作。

13 结构体,struct

Go语言使用结构体来描述现实业务逻辑中实体。是自定义类型。结构体是由一系列数据构成的数据集合,一系列数据类型可以不同。

定义结构体,使用struct关键字:
type 结构体名 struct {
成员1 类型
成员2 类型

}

示例:

// 定义Product结构
type Product struct {
  // 两个成员
  name  string
  price float64
}

// 构造函数
func newProduct(name string, price float64) *Product {
  return &Product{name, price}
}

// 成员方法,接收器方式
func (p *Product) getName() string {
  return "《" + p.name + "》"
}

// 方法2
func (p *Product) setPrice(price float64) *Product {
  p.price = price
  return p
}

func main() {
  // 构造Product型数据p1
  var p1 = newProduct("BlockChain", 42.5)
  // 访问成员
  fmt.Println(p1.name)
  // 通过接收器访问方法
  fmt.Println(p1.getName())
  var p2 = newProduct("GoLang", 30.5)
  p2.setPrice(44.5)
  fmt.Println(p2.price)
}

详见结构体操作。

14 接口,interface

接口是一种协议,用来规范方法的调用和定义的协议,目的是保证设计的一致性,便于模块化开发以及通讯。Go语言中,也视为一种类型。
定义语法:

type 接口名 interface {
方法1( 参数列表 ) 返回值类型列表
方法2( 参数列表 ) 返回值类型列表

}

可以理解成没有方法体的方法。
示例:

// 定义Product结构
type Product struct {
  // 两个成员
  name  string
  price float64
  // say   func()
}

// 构造函数
func newProduct(name string, price float64) *Product {
  return &Product{name, price}
}

// 成员方法,接收器方式
func (p *Product) getName() string {
  return "《" + p.name + "》"
}

// 方法2
func (p *Product) setPrice(price float64) *Product {
  p.price = price
  return p
}

// 定义接口
type ProductInterface interface {
  getName() string
  setPrice(price float64) *Product
}

func main() {
  // 构造Product型数据p1
  var p1 = newProduct("BlockChain", 42.5)
  // pi为接口,为其赋值p1,就意味着使用接口规范p1,若p1不满足接口定义则出错
  var pi ProductInterface = p1
  // 利用接口调用方法
  fmt.Println(pi.getName())
}

详见接口操作

15 函数,func()

Go语言中,函数可以作为数据存储变量中,此时变量为函数类型func()。可以通过该变量访问到这个函数。可以用在结构体成员定义上。
语法示例:

func sayHello(name string) {
  fmt.Println("Hello, ", name)
}

func main() {
  // 函数本身就是函数类型
  fmt.Printf("%T(%v)\n", sayHello, sayHello) // func(string)(0x48fe20)
  // 赋值给变量
  var f = sayHello
  fmt.Printf("%T(%v)\n", f, f) // func(string)(0x48fe20)
  // 匿名函数也是函数类型
  var af = func() {
  }
  fmt.Printf("%T(%v)\n", af, af) // func()(0x490080)
}

参见函数使用。

完!
原文出自:小韩说课
微信关注:小韩说课

小韩说课

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 林鹿说第一次亲吻石泉就像是在炎热的夏季绕着操场跑了十圈浑身大汗吃了一颗冰镇樱桃。 林鹿第一次见到石泉是在南京的一家...
    大熊爸爸阅读 358评论 0 0
  • 时间屏住呼吸 在字句里藏下潜台词 阳光在一点点消瘦 直到消瘦成一条瘦瘦的影子 此时,浅显的言语才渐渐有意义 好像一...
    白壁阅读 257评论 4 8
  • 浮华一生,你可以选择轰轰烈烈,也可以平凡度日。我想,为自己选择什么,是重要的。 为了交到好朋友,我选择...
    全仔阅读 287评论 0 1
  • 原文地址:http://www.keyunq.com/ 给sublime安装插件管理器一、简单的安装方法使用Ctr...
    isaaCyu阅读 390评论 0 0