第三章 基础数据类型

Go语言将数据类型分为四类:

  • 基础类型

    • 数字

      • 整数
      • 浮点数
      • 复数
    • 字符串
    • 布尔
  • 复合类型
    • 数据
    • 结构体
  • 引用类型
    • 指针
    • 切片
    • 字典
    • 函数
    • 通道
  • 接口类型

在此章节中先介绍基础类型。

3.1 整型

Go语言中提供了有符号数和无符号数两种整型运算。
有符号数有:int8, int16, int32, int64
无符号数有:uint8, uint16, uint32, uint64

此外还有两种针对特定CPU平台机器字大小的有符号数int和无符号数uint, 它们的大小与硬件平台有关。

rune类型与int32等价
byte类型与uint8等价

一般使用byte类型强调数值是一个原始数据,而并非是一个小整数。

int, uint, int32他们属于不同的类型,不能直接进行操作(需要强转)。

Go语言中有关算数运算、逻辑运算、比较运算的二元运算符,它们按照递减顺序排列如下:

*     /     %    <<    >>   &    &^
+     -     |    ^
==   !=     <    <=    >    >=
&&
||
* / % << >> & &^
+ - \ ^
== != < <= > >=
&&
||
  • 二元运算符有五种优先级(见上图),同一优先级之间,使用左优先结合的原则,但是可以使用括号来提升优先级。例如 mask & 1 << 28, 因为& <<属于相同优先级,因此先计算mask&1, 然后再将其结果左移28位。我们可以使用括号来提升优先级:
    mask & (1 << 28)

  • 算术运算符+、-、*和/ 可以适用于整数、浮点数、复数运算,但是取模运算符%只能用于整数之间

  • 在Go语言中,%取模运算的符号与被取模的符号数总是一致的。例如-5%3=-2-5%-3=-2

  • 两个相同的整数类型可以使用下面的二元比较运算符进行比较,其结果为布尔型:

    • ==
    • !=
    • <
    • <=
    • >
    • >=

在Go中,有两个一元运算符:

    +   一元加法-   负数

对于整数,+x是0+x的简写; -x是0-x的简写;
对于浮点数和复数,+x就是x;-x就是x的复数。

Go语言中还提供了bit位操作运算符,前四个不区分有符号数还是无符号数:

    &       位运算AND|       位运算OR^       位运算XOR&^      位清空(AND NOT)<<      左移>>      右移

位运算^ 作为二元运算符时按位异或;当作为一元运算符时表示按位取反
移位操作(如x<<n),n要求必须为无符号数,x可以是有符号数也可以是无符号数。左移运算,使用0填充右边空缺Bit位;无符号数右移也是用0填充左边的空缺位,但是有符号数右移则会使用符号位填充左边的空缺位(负数右移仍然为负数)。

func main() {var i int8 = -64fmt.Println(i)fmt.Println(i >> 2)fmt.Println(i >> 4)fmt.Println(i >> 5)fmt.Println(i >> 6)fmt.Println(i >> 10)fmt.Printf("%09b\n", i)fmt.Printf("%09b\n", i>>2)fmt.Printf("%09b\n", i>>4)fmt.Printf("%09b\n", i>>5)fmt.Printf("%09b\n", i>>6)fmt.Printf("%09b\n", i>>10)
}

结果:

    -64-16-4-2-1-1-01000000-00010000-00000100-00000010-00000001-00000001

强制类型转换:

func main() {var apples int32 = 1var oranges int16 = 2var compote int = apples + oranges}
如果未做转换,则无法编译通过,提示如下错误:
# command-line-arguments
section3\forceConv.go:7:27: invalid operation: apples + oranges (mismatched types int32 and int16)

而比较常用的解决办法是:类型强制转换. 之后程序便可以成功编译运行。

    var compote int = int(apples) + int(oranges)

同其他语言一样,在高精度向低精度类型强制转换过程中存在丢失精度的问题

关于使用Printf函数的注意事项:

func main() {x := 100fmt.Printf("%d %[1]x %#[1]x %#[1]b\n", x)}
执行结果如下:
100 64 0x64 0b1100100

可以看出:

  • 在%之后的[1]用来告诉Printf函数再次使用第一个操作数
  • 在%之后的#用来告诉Printf函数在使用%o、%x、%X等输出时添加0、0x、0X的前缀。
  • 字符使用%c参数打印,或者是用%q参数打印带单引号的字符
    这两个东西都比较好用…切记切记

3.2浮点类型

Go语言提供了两种精度的浮点数,float32和float64。
file:///F:/golang/Bible/section3/surface.xml

3.3 复数

Go语言提供了两种精度的复数类型:complex64和complex128,分别对应float32和float64两种浮点数精度。
内置的complex函数用于构建复数,内建的real和imag函数分别返回复数的实部和虚部:

func main() {var x complex128 = complex(1, 2)var y complex128 = complex(2, 3)/*复数相乘是交叉相乘,类似于(a+b) * (c+d) */fmt.Println(x * y)fmt.Println(real(x * y))fmt.Println(imag(x * y))fmt.Println(1i * 1i)fmt.Println(cmplx.Sqrt(-1))
}

执行结果如下:

(-4+7i)
-4
7
(-1+0i)
(0+1i)

3.4 布尔型

一个布尔类型的值只有两种:true和false。
if和for语句的条件部分都是布尔类型的值,并且==和<等比较操作也会产生布尔型的值。

  • &&运算符的优先级高于||, 因此下面的代码没有问题
if 'a' <= c && c <= 'z' ||'A' <= c && c <= 'Z' ||'0' <= c && c <= '9' {/* c is letter or digit  */}
  • [x]布尔值不会隐式转换为0或者1,反之亦然。两者之间需要做显式转换
func itob(i int) bool {return i != 0
}func btoi(b bool) int {if b {return 1}return 0
}

3.5字符串

  • 在Go中,字符串是一个常量,不可修改的
  • 内置的len函数可以返回一个字符串中的字节数目(不是rune字符数目)
  • 越界访问会导致panic异常
  • 子字符串操作s[i:j]基于原始的s字符串的第i个字节开始到第j个字节(并不包含j本身)生成一个新字符
  • 不管i还是j都可能被忽略,当它们被忽略时将采用0作为开始位置,采用len(s)作为结束的位置

字符串操作demo:

    func main() {s := "hello, world!!!"fmt.Println(len(s))fmt.Printf("s[0]= %[1]c %[1]d\n", s[0])fmt.Printf("s[7]= %[1]c %[1]d\n", s[7])//fmt.Println(s[len(s)]) /*index out of range [15] with length 15*//*支持索引访问,如果超出范围仍然会有panic异常*/fmt.Println(s[2:8])fmt.Println(s[:8])fmt.Println(s[2:])fmt.Println(s[:])/*可以用来拼接字符串*/fmt.Println("Oh,shit" + s[5:])t := ss += "Oh,Ye!!! Oh Ye"/*t没有变化,s字符串被追加了一段*/fmt.Println(t)fmt.Println(s)s[0] = 'H' //cannot assign to s[0]
}

3.6 常量

  • 常量表达式的值在编译期计算,而不是在运行期。
  • 常量的值不可修改,这样可以防止在运行期被意外或恶意的修改。
  • 和变量声明一样,可以批量声明多个常量;这比较适合声明一组相关的常量:
    const (e = 2.71828182845904523536028747135266249775724709369995957496696763pi = 3.14159265358979323846264338327950288419716939937510582097494459)
  • 如果是批量声明的常量,除了第一个外其它的常量右边的初始化表达式都可以省略,如果省略初始化表达式则表示使用前面常量的初始化表达式写法,对应的常量类型也一样的, 详见下面例子:
    func main() {const (a = 1bc = 2d)fmt.Println(a) //1fmt.Println(b) //1fmt.Println(c) //2fmt.Println(d) //2}

这个是itoa常量生成器的一个前提。

3.6.1 itoa常量生成器

常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行itoa值加一。

例如:

const (Sunday Weekday = iotaMondayTuesdayWednesdayThursdayFridaySaturday
)func main() {fmt.Println(Sunday)     //0fmt.Println(Monday)     //1fmt.Println(Tuesday)    //2fmt.Println(Wednesday)  //3fmt.Println(Thursday)   //4fmt.Println(Friday)     //5fmt.Println(Saturday)   //6
}

下面是一个更复杂的例子,每个常量都是1024的幂

const (_ = 1 << (10 * iota)KiB     // 1024MiB     // 1048576GiB     // 1073741824TiB     // 1099511627776 (exceeds 1 << 32)PiB     // 1125899906842624EiB // 1152921504606846976ZiB     // 1180591620717411303424 (exceeds 1 << 64)YiB     // 1208925819614629174706176
)

不过iota常量生成规则也有其局限性。例如,它并不能用于产生1000的幂(例如KB、MB等)

3.6.2 无类型常量

Go语言的常量有个不同寻常之处:存在无类型的常量,且精度更高。
许多常量并没有一个明确的基础类型。编译器为这些没有明确的基础类型的数字常量提供比基础类型更高精度的算术运算
只有常量可以是无类型的

《Go语言圣经》阅读笔记:第三章基础数据类型相关推荐

  1. 《Go语言圣经》学习笔记 第三章 基础数据类型

    <Go语言圣经>学习笔记 第三章 基础数据类型 目录 整型 浮点数 复数 布尔型 字符串 常量 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. Go语言小白学习笔记, ...

  2. 深入理解 C 指针阅读笔记 -- 第三章

    Chapter3.h #ifndef __CHAPTER_3_ #define __CHAPTER_3_/*<深入理解C指针>学习笔记 -- 第三章*//*它们都保存在栈中的什么位置?*/ ...

  3. 《Go语言圣经》笔记(1-4章)

    第一章.入门 第一章的命令行部分最后学!先学后面 1.hello world Go不需要加分号 "{" 符号必须和关键字func在同一行,不能独自成行.并且在 x+y 这个表达式中 ...

  4. 《机器学习》阅读笔记 第三章

    Contents 1. 不同学科中的线性模型[^1] 2. 线性模型:回归任务 2.1 估计方法 2.2 正则化 2.3 广义线性模型 3. 线性模型:分类任务 3.1 对数几率回归 线性判别分析(L ...

  5. 《Concurrency in Go》阅读笔记 -- 第三章:Go语言并发组件

    <Concurrency in Go> 本章节从goroutine入手,讲解go语言的各种并发原语.在讲解完goroutine之后,对于传统的内存同步访问的并发原语:sync包中的Mute ...

  6. Java自我学习第三章基础数据类型

    Java的基本数据类型(掌握) 1.整型系列 (1)byte:字节类型 占内存:1个字节 存储范围:-128~127 (2)short:短整型类型 占内存:2个字节 存储范围:-32768~32767 ...

  7. 《Go语言圣经》学习笔记 第四章 复合数据类型

    <Go语言圣经>学习笔记 第四章 复合数据类型 目录 数组 Slice Map 结构体 JSON 文本和HTML模板 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. ...

  8. Android群英传神兵利器读书笔记——第三章:Android Studio奇技淫巧

    Android群英传神兵利器读书笔记--第三章:Android Studio奇技淫巧 这篇文章篇幅较长,可以使用版权声明下面的目录,找到感兴趣的进行阅读 目录 3.1 Android Studio使用 ...

  9. Go语言圣经阅读-第二周

    Go语言圣经阅读-第二周 2.4. 赋值 使用赋值语句可以更新一个变量的值,最简单的赋值语句是将要被赋值的变量放在=的左边,新值的表达式放在=的右边. x = 1 // 命名变量的赋值 *p = tr ...

  10. 计算机系统导论第九章,计算机系统导论 -- 读书笔记 -- 第三章 程序的机器级表示 (持续更新)...

    计算机系统导论 -- 读书笔记 -- 第三章 程序的机器级表示 (持续更新) 第三章 程序的机器级表示 3.1 历史观点 3.2 程序编码 1. 命令行 (1)编译 Linux> gcc -Og ...

最新文章

  1. 这两者需要映射到相同的服务器,从而无法打开项目的解决方法:
  2. dell存储Linux配置,Dell MD3200远程存储的特殊配置
  3. hdu4995 (不错的小模拟)
  4. java基础提升篇:Java 序列化的高级认识
  5. 虚拟服务器放2个网站,如何一个虚拟主机空间放两个网站的基本原理
  6. [react] 你有用过哪些React的UI库?它们的优缺点分别是什么
  7. 【Swift学习】Swift编程之旅(一)
  8. 输出dag的所有拓扑排序序列_算法学习笔记(53): 拓扑排序
  9. webpack之react开发前准备
  10. php秒数怎么转换为时间格式,php将秒数转换为时间(年、月、日、小时…)
  11. win32以动态链接库导出类及其成员变量
  12. oracle lead_lag wm_concat,oracle函数 lag()和lead()
  13. pix4d怎么查看点云数据_PIX4D的两种像控点刺点方式探讨
  14. Exadata中最有用的功能-存储索引
  15. 计算机CPU高温,电脑cpu温度高怎么办?别怕,三招搞定
  16. Flink容错机制(一)
  17. 淘宝抢购Python脚本
  18. 2021年度科技行业有哪些大事件?“杰出科技奖”公布36家企业领先科技技术
  19. 从Github下载laravel项目遇到的坑
  20. [译]Flutter缓存管理库flutter_cache_manager

热门文章

  1. Elasticsearch 批量导入数据
  2. 七宗罪----人性本恶
  3. 音视频学习(五)——H.264视频码流
  4. 电路板上的这些标志你都知道是什么含义吗?——详解电子产品认证类型
  5. 信源编码与信道编码区别(十一)
  6. 银行软开开发篇[转]
  7. rabbitmq创建缓存连接工厂
  8. 数学建模论文写作要求
  9. eclipse基础实用教程
  10. 计算机病毒手动查杀,如何手动查杀计算机病毒