Go 学习笔记(6):基本类型

本文深入探讨Go语言中的各种基础数据类型,包括整型、浮点型、复数、布尔型、字符串以及它们的表示方法和操作。同时,文章详细讲解了不同类型之间的转换和格式化打印技巧。

整型

Go 语言提供多个整数类型,根据计算架构可分为有符号整数类型 int 和无符号整数类型 uint

  • 在 32 位操作系统中,intuint 使用 32 个 bit 表示数值,即 4 个字节;
  • 在 64 位操作系统中,intuint 使用 64 个 bit 表示数值,即 8 个字节。

除了这两个和计算架构有关的整数类型外,还有 8 个和操作系统无关、显式表示宽度的整数类型:

整数范围符号宽度(bit范围
int88-128 ~ 127
int1616-32768 ~ 32767
int3232-2,147,483,648 ~ 2,147,483,647
int6464-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
uint880 ~ 255
uint16160 ~ 65535
uint32320 ~ 4,294,967,295
uint64640 ~ 18,446,744,073,709,551,615

int 类型的最高位的 bit 表示正负,所以其表示的整数范围缩小了,而 uint 使用所有比特位表示数值。

另外,还有一个整数类型:uintptr,没有指定具体的 bit 大小但是足以容纳指针,只有在底层编程时才用到,特别是 Go 语言和 C 语言函数库或操作系统接口相交互的地方。

rune 和 byte

runeint32 等价,可以看作 int32 的别名类型,byte 则和 uint8 等价。

一个 rune 类型可表示一个 Unicode 字符,也就是 Unicode 代码点。一个 Unicode 代码点通常由 U+ 和一个以十六进制表示法表示的整数表示。例如,英文字母 AUnicode 代码点为 U+0041

8 进制和 16 进制

  • 增加前缀 0 来表示 8 进制数,如:077
  • 增加前缀 0x0X 来表示 16 进制数,如:0xFF
a, b := 077, 0xFF
fmt.Printf("%o %X", a, b)  //77 FF
复制代码

浮点型

Go 提供两种精度的浮点类型:float32float64,存储这两个类型的值的空间分别需要 4 个字节和 8 个字节。浮点数范围极限值可以在 math 包找到:math.MaxFloat32math.MaxFloat64

类型范围
float32约 1.4e-45 ~ 3.4e38
float64约 4.9e-324 ~ 1.8e308

float32 精确到小数点后 7 位,float64 精确到小数点后 15 位。由于精确度的缘故,在使用 == 或者 != 来比较浮点数时应当非常小心。

因为 float32 的有效 bit 位只有 23 个,其它的 bit 位用于指数和符号,当整数大于 23bit 能表达的范围时,float32 的表示将出现误差。所以应该尽量使用 float64,因为 math 包中所有有关数学运算的函数都会要求接收这个类型。

注意,没有 float 类型。

表示方法

  1. 小数点表示:var a float64 = 1.2

  2. 科学计数法(Ee 皆可):

     var a float64 = 3.7E-2
     fmt.Println(a == 0.037)  // true
     
     var b float64 = 2.3e+3   // 或 2.3e3
     fmt.Println(b == 2300)   // true
    复制代码

注意:

  • Go 语言中,浮点数的相关部分只能由 10 进制表示法表示,而不能由 8 进制表示法或 16 进制表示法表示。比如,03.7 表示的一定是浮点数 3.7

复数

Go 语言有两种精度的复数类型:complex64complex128,存储这两个复数类型的值分别需要 8 和 16 个字节。

complex64 类型的值由两个 float32 类型的值分别表示复数的实数部分和虚数部分;而 complex128 类型的值由两个 float64 类型的值分别表示复数的实数部分和虚数部分。

// 定义复数
var a complex64 = 10 + 5i        // 10+5i
var b complex64 = complex(2, 3)  // 2+3i

// 获取实数和虚数部分
fmt.Println(real(a), real(b))    // 10  2,float32 类型
fmt.Println(imag(a), imag(b))    // 5  3,float32 类型
复制代码

使用 ==!= 对复数进行比较运算时,注意精确度。

如果对内存的要求不是特别高,最好使用 complex128 类型,因为相关函数都使用这个类型的参数。

布尔型

  • true
  • false
var a bool = true
b := false
复制代码

字符串

一个字符串类型的值可以代表一个字符序列,Go 使用 UTF-8 将字符串(或者说字符序列)编码为字节数组。

注意,使用内置函数 len 会得到字节数组的长度,而不是表面上的长度。

表示

  • 解释字符串:使用双引号括起来,其中的相关的转义字符将被替换;
  • 原生字符串:使用反引号括起来,其中的值是所见即所得的(除了回车符)。

解释字符串中的转义字符包括:

  • \n:换行符
  • \r:回车符
  • \ttab
  • \u\UUnicode 字符
  • \\:反斜杠自身
  • ......

索引

对于 ASCII 字符串,可以通过索引来获取其内容:

  • str[0]:第 1 个字节
  • str[i - 1]:第 i 个字节
  • str[len(str)-1]:最后 1 个字节(不支持负数索引)
  • s[i:j]:第 i 个字节到第 j 个字节(不包含 j 本身)
  • 超出索引范围会导致 panic 异常
  • &str[i]:错误,获取字符串中某个字节的地址的行为是非法的。
a := "hello"
fmt.Printf("%q\n", a[0])    // h
fmt.Printf("%q\n", a[4])    // 0
fmt.Printf("%q\n", a[0:5])  // hello,不包括a[5]
fmt.Printf("%q\n", a[:4])   // hell,不包括a[4]
fmt.Printf("%q\n", a[2:])   // llo
复制代码

拼接

s1 := "hello" + " world"

// 由于编译器行尾自动补全分号的缘故,+ 必须放在第一行
s2 := "hello" +  
      " world"
复制代码

当涉及到大量拼接操作时,+ 并不高效,更好的方法是使用函数 strings.Join(),字节缓冲 bytes.Buffer 拼接效率还要更高。

strings

strings 中有很多操作字符串的方法,使用 strings.HasPrefix 的形式调用:

  • HasPrefix(s, prefix string) bool:判断字符串 s 是否以 prefix 开头

  • HasSuffix(s, suffix string) bool:判断字符串 s 是否以 suffix 结尾

  • Contains(s, substr string) bool:判断字符串 s 是否包含 substr

  • Index(s, str string) int:返回字符串 str 在的首个字符在字符串 s 中的首次出现的位置的索引,-1 表示字符串 s 不包含字符串 str

  • LastIndex(s, str string) int:  返回字符串 str 在的首个字符在字符串 s 中的最后出现的位置的索引,-1 表示字符串 s 不包含字符串 str

  • IndexRune(s string, r rune) int:查询 ASCII 编码的字符在父字符串中的位置

  • Replace(str, old, new, n) string:字符串替换,将字符串 str 中的前 n 个字符串 old 替换为字符串 new,并返回一个新的字符串,如果 n = -1 则替换所有字符串 old 为字符串new

  • Count(s, str string) int:用于计算字符串 str 在字符串 s 中出现的非重叠次数

  • Repeat(s, count int) string:用于重复 count 次字符串 s 并返回一个新的字符串

  • ToLower(s) string:转换为小写

  • ToUpper(s) string:转换为大写

  • Trim(s string, cutset string) string:删除头尾指定的 Unicode 字符

  • TrimLeft(s string, cutset string) string:删除头部指定的 Unicode 字符

  • TrimRight(s string, cutset string) string:删除尾部指定的 Unicode 字符

  • TrimSpace(s string) string:删除头尾的空格

  • TrimPrefix(s, prefix string):返回头部去掉 prefix 的字符串

  • TrimSuffix(s, suffix string) string:返回尾部去掉 suffix 的字符串

  • Fields(s string) []string:使用空白符(包括连续的空白符)将字符串 s 切割为一个 slice

  • strings.Split(s, sep) []string:使用 sep 作为分割符对 s 进行分割,返回 slice

  • strings.Join(sl []string, sep string) string:将元素类型为 stringslice 使用分割符号 sep 来拼接组成一个字符串。

  • NewReader(str):生成一个 Reader 并读取字符串中的内容,然后返回指向该 Reader 的指针。类似 Read()[]byte 中读取内容,ReadByte()ReadRune() 从字符串中读取下一个 byte 或者 rune

strconv

strconv 处理字符串与其它类型的转换。

  • strconv.IntSize:获取当前平台下 int 类型所占的位数
  • 任何类型 T 转换为字符串都可以
  • 将字符串转换为其它类型并不总是都可以

格式化打印

fmt 包中的几个打印方法:

方法说明
Print输出到控制台(不接受任何格式化,它等价于对每一个操作数都应用 %v
Println输出到控制台并换行
Printf格式化打印输出。注意,如果不用占位符,直接使用此方法,只能输出字符串类型的变量。
Sprintf格式化并返回一个字符串,不会打印
Fprintf来格式化并输出到 io.Writers 而不是 os.Stdout
适用类型占位符说明
普通%v值的默认格式
%+v添加字段名,如结构体
%#vGo语法表示
%T相应值的类型的Go语法表示
%%字面上的百分号
整型%b二进制表示
%c相应Unicode码点所表示的字符
%d十进制表示
%o八进制表示
%q单引号围绕的字符字面值,由Go语法安全地转义
%x十六进制表示,字母形式为小写 a-f
%X十六进制表示,字母形式为大写 A-F
%UUnicode格式:U+1234,等同于 "U+%04X"
浮点数及复数%b无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat 中的 'b' 转换格式一致。例如 -123456p-78
%e科学计数法,例如 -1234.456e+78
%E科学计数法,例如 -1234.456E+78
%f小数点表示法,如 1.23
%g根据情况选择 %e%f 以产生更紧凑的(无末尾的0)输出
%G根据情况选择 %E%f 以产生更紧凑的(无末尾的0)输出
字符串和字节切片%s字符串或切片的无解译字节
%q双引号围绕的字符串,由Go语法安全地转义
%x十六进制,小写字母,每字节两个字符
%X十六进制,大写字母,每字节两个字符
指针%p十六进制表示,前缀 0x
布尔型%ttrue 或 false
其它+打印数值的正负号;对于%q(%+q)保证只输出ASCII编码的字符
-在右侧填充空格(左对齐)
#%#b、%#o、%#x 添加前缀打印;%#q:打印原始 (即反引号围绕的)字符串;%#U:打印 Unicode 编码形式
空格为数值中省略的正负号留出空白(% d)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值