爱上开源之golang入门至实战第四章-数据基本类型

爱上开源之golang入门至实战第四章-数据基本类型

爱上开源之golang入门至实战第四章-数据基本类型

第四章 数据类型

4.1 基本类型

4.1.1 布尔型

布尔型的值只可以是常量 true 或者 false

一个简单的例子

var exists bool = truestop := true

Go 言中不允许将整型强制转换为布尔型,

一段简单代码如下:

var isCome bool = true fmt.Println("%d\n", int(isCome))

编译错误,输出如下

# go-in-practice/code/charpter-01 [go-in-practice/code/charpter-01.test].\lesson03_test.go:22:26: cannot convert isCome (variable of type bool) to type int

同样的 布尔型无法参与数值运算,也无法与其他类型进行转换。

4.1.2 数字类型

可以分为整数类型 int 和浮点类型 float32、float64,Go 语言支持整型和浮点型数字,并且原生支持复 数,其中位的运算采用补码;Go 也有基于架构的类型,例如:int、uint 和 uintptr,这些类型的长度都是根据运行程序所在的 操作系统类型所决定的。

整型类型

按长度分为:int8、int16、int32、int64,还有对应的无符号整型: uint8、 uint16、uint32、uint64。其中,uint8就是我们熟知的byte型,int16对应C语言中的short型,int64对应C语言中的long型。

goLang := 100 fmt.Printf("%d %T\n", goLang, goLang)=== RUN TestLesson03_1_1100 int--- PASS: TestLesson03_1_1 (0.00s)

如何在程序查看某个变量的字节大小和数据类型

var goLang uint64 = 100 fmt.Printf("%d %T %d\n", goLang, goLang, unsafe.Sizeof(goLang))=== RUN TestLesson03_1_2100 uint64 8--- PASS: TestLesson03_1_2 (0.00s)

浮点类型

表示小数,Go语言里支持float32和float64两种浮点类型。浮点数能够表示的范围可以从很小到很巨大,这个极限值范围可以在math包中获取,math.MaxFloat32表示float32的最大值,大约是3.4e38,math.MaxFloat64大约是1.8e308,两个类型最小的非负值大约是1.4e-45和4.9e-324。

float32大约可以提供小数点后6位的精度,作为对比,float64可以提供小数点后15位的精度。通常 情况应该优先选择float64,因为float32的精确度较低,在累积计算时误差扩散很快,而且 float32能精确表达的最小正整数并不大,因为浮点数和整数的底层解释方式完全不同。

复数

复数类型相对用的很少,主要是数学学科专业会用上。分为两种类型 complex64和complex128 前部分是实体后部分是虚体

复数使用 re + imI 来表示,其中 re 代表实数部分,im 代表虚数部分,I 代表根号负 1。

示例:

var c1 complex64 = 5 + 10i fmt.Printf("%v\n", c1) // 输出: 5 + 10i

=== RUN TestLesson03_1(5+10i)--- PASS: TestLesson03_1 (0.00s)

如果 re 和 im 的类型均为 float32,那么类型为 complex64 的复数 c 可以通过以下方式来获 得:complex(re, im)

函数 real(c) 和 imag(c) 可以分别获得相应的实数和虚数部分。

示例

var c2 complex64 = complex(5.0, 10.0) fmt.Printf("%f %f\n", real(c2), imag(c2))

=== RUN TestLesson03_15.000000 10.000000--- PASS: TestLesson03_1 (0.00s)PASS

其他数字类型

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is// used, by convention, to distinguish byte values from 8-bit unsigned// integer values.type byte = uint8

// rune is an alias for int32 and is equivalent to int32 in all ways. It is// used, by convention, to distinguish character values from integer values.type rune = int32

注意:在Golang里,没有char类型; 可以使用rune类型,来代替char类型或者字符串里的单个字符;

下面是一段示例代码

func TestLesson03_2(t *testing.T) { var c rune = '中' fmt.Printf("%c\n", c) c = []rune("中国红")[1] fmt.Printf("%c\n", c) c = []rune("中国红")[2] fmt.Printf("%c\n", c)}

运行结果

=== RUN TestLesson03_2中国红--- PASS: TestLesson03_2 (0.00s)

4.1.3 字符串

字符串在Go 语言中以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、 float32等)。字符串的值为双引号中的内容,可以在 Go 语言的源码中直接添加非 SCII 码字莉, Go语言使用UTF-8格式编码Unicode字符,每个字符对应一个rune类型。 一旦字符串变量赋值之后,内部的字符就不能修改,英文是一个字节,中文是三个字节。

字符常(变)量是用单引号('')括起来的单个字符。例如:

var c1 byte = 'a'var c2 int = '中'var c3 byte = '9'

字符串是用双引号(“”)括起来的n个字符(n>=0)。例如下面的字符串定义

hello := "hello world"multiple := `This is a multiple row`

小技巧

Golang支持使用 ``的方式,来赋值带有格式化的字符串;和javascript以及C#中的类似用法

字符串可以通过+的方式和其他字符串类型进行拼接运算; 可以使用fmt.Sprintf函数进行格式化的运输

示例代码

hello := "hello"world := "world"all := hello + " " + worldfmt.Printf("%s\n", all)

=== RUN TestLesson03_2_1hello world--- PASS: TestLesson03_2_1 (0.00s)

hello := "hello" world := "world" all := fmt.Sprintf("%s %s %s", hello, " ", world)

=== RUN TestLesson03_2_2hello world--- PASS: TestLesson03_2_2 (0.00s)

Golang语言里提供了strings包,封装了很多非常有用的关于字符串对象的函数; 同时提供了strconv包对字符串进行转换的函数包;示例代码如下

fmt.Printf("%s\n", strings.ReplaceAll("abacad", "a", "1")) fmt.Printf("%d\n", strings.Index("abacad", "a")) fmt.Printf("%v\n", strings.Split("abacad", "c"))

=== RUN TestLesson03_2_31b1c1d0[aba ad]--- PASS: TestLesson03_2_3 (0.00s)

fmt.Printf("%s\n", strconv.Itoa(12)) fmt.Printf("%s\n", strconv.Itoa(012)) fmt.Printf("%s\n", strconv.Itoa(0x12)) goLang, _ := strconv.ParseInt("ffff", 16, 64) fmt.Printf("%d %T %d\n", goLang, goLang, unsafe.Sizeof(goLang))

=== RUN TestLesson03_2_412101865535 int64 8--- PASS: TestLesson03_2_4 (0.00s)

字符串可以直接支持range循环;一个range循环会在每次迭代时,得到一个UTF-8编码的字符。每次循环时,循环的索引是当前文字

的起始位置,以字节为单位,元素的类型是(int32/rune)

for idx, one := range "中国GOLang" { fmt.Printf("%q %#U %d %T %d\n", rune(one), one, idx, one, unsafe.Sizeof(one)) }

=== RUN TestLesson03_2_5'中' U+4E2D '中' 0 int32 4'国' U+56FD '国' 3 int32 4'G' U+0047 'G' 6 int32 4'O' U+004F 'O' 7 int32 4'L' U+004C 'L' 8 int32 4'a' U+0061 'a' 9 int32 4'n' U+006E 'n' 10 int32 4'g' U+0067 'g' 11 int32 4--- PASS: TestLesson03_2_5 (0.00s)

Go支持Unicode(UTF-8),字符同样称为Unicode 代码或者 rune,并在内存中使用 int32 来表示。在文档中,一般使用格式 U+hhhh 来表示,其中 h 表示一个 16 进制数。 rune是Go 当中的一个类型,是 int32 的别名。 在书写 Unicode 字符时,需要在 16 进制数之前加上前缀 \u 或者 \U。 因为 Unicode 至少占用 2 个字节,所以我们使用 int16 或者 int 类型来表示。如果需要使用到 4 字节,则会加上 \U 前缀;前缀 \u 则总是紧跟着长度为 4 的 16 进制数,前缀 \U 紧跟着长 度为 8 的 16 进制数。

var ch int = '\u0041' var ch2 int = '\u03B2' var ch3 int = '\U00101234'