Go程序设计语言学习--基本类型

基本数据

Go的数据类型分为四大类:

基础类型:数字、字符串和布尔型

聚合类型:通过组合各种简单类型得到的更复杂的数据类型

引用类型:指针、map、slice、函数和通道

接口类型

一、整数

Go的数值类型包括了几种不同大小的整数、浮点数和复数。有符号整数分为四种大小:8位、16位、32位、64位,分别用int8、int16、int32、int64表示,对应无符号整数用uint8、uint16、uint32、uint64表示。此外还有int和uint类型,这两种类型大小相等,都是32位或64位,不同的编译器可能会选择不同的大小。int是目前使用最广泛的数据类型。

rune是int32的同义词,常用于指明一个值是Unicode码点。byte是int8的同义词,强调一个值是原始数据,而非量值。

无符号整数uintptr,大小不明确,但足以完整存放指针,仅用于底层编程。

int、uint、uintptr与大小有别的数据类型不同,如需转换则需要显式转换。

Go的二元操作符涵盖了算术、逻辑和比较等运算,按优先级降序排列如下:

* / % << >> & &^

+ - | ^

== != < <= > >=

&&

||

同一行的操作符优先级相同,前两行的运算符都有对应的赋值运算符(如+=)。

就Go而言,取模余数的正负号总与被除数一致,-5%3和-5%-3结果都是-2。除法运算的行为取决于操作符是否都为整型,如5.0/4.0=1.25、5/4=1。

不论有符号数还是无符号数,若表示算术运算结果所需的位超过该类型的范围,就称为溢出,溢出的高位部分会被丢弃。

比较表达式本身的类型是布尔类型。全部基本类型的值都可以进行比较,两个相同类型的值可以用!=和==比较,整数、浮点数和字符串还可以根据比较运算符进行排序。

Go也具备位运算符。作为二元运算符时,表示异或;作为一元运算符时,表示按位取反或按位取补。运算符&是按位清除:z=x&^y,若y的某位是1,的z的对应位等于1,否则等于x的对应位。

算术上,左移运算x<<n等价于x*(2^n),右移运算则为除。左移以0填补右边空位,无符号数右移以0填补,而有符号数右移以符号位的值填补。无符号整数往往只用于位运算和特定算术运算符。一般而言,无符号整数极少用于表示非负值。

浮点数转成整型,会舍弃小数部分,趋零截尾(正值向下取值,负值向上取值)。

fmt的技巧:通常Printf的格式化字符串含有多个%谓词,%后的副词[1]告知Printf重复使用第一个操作数。%o、%x、或%X后的副词#告知Printf输出对应的前缀0、0x或0X。用%c输出文字符号,若希望输出带有单引号则用%q。

o := 0666
fmt.Printf("%d %[1]o %#[1]o\n", o) //"438 666 0666"
x := int64(0xdeadbeef)
fmt.Printf("%d %[1]x %#[1]X\n", x) //"3735928559 deadbeef 0xdeadbeef 0XDEADBEEF"

ascii := 'a'
unicode = '国'
newline := '\n'
fmt.Printf("%d %[1]c %[1]q\n", ascii) //"97 a 'a'"
fmt.Printf("%d %[1]c %[1]q\n", unicode) //"22269 国 '国'"
fmt.Printf("%d %[1]q\n", newline) //"10 '\n'"

二、浮点数

Go具有两种大小的浮点数float32和float64。常量math.MaxFloat32是float32的最大值,大约为3.4e38,math.MaxFloat64约为1.8e308。最小的正浮点值大约为1.4e-45和4.9e-324。十进制下,float32的有效数字约为6位,float64约为15位,大多数情况下优先选用float64。float32能精确表示的正整数范围有限:

var f float32 16777216 //1 << 24
fmt.Println(f == f+1) //"true"

小数点前后的数组可以省略(.707、1.)。浮点值通过Printf的%g输出,会自动保持足够的精度。

三、复数

Go具备两种大小的复数complex64和complex128,二者分别由float32和float64构成。内置的complex函数根据给定的实部和虚部创建复数,内置的real和imag函数分别提取复数的实部和虚部:

var x complex128 = complex(1, 2) //1+2i
var y complex128 = complex(3, 4) //3+4i
fmt.Println(x * y) //-5+10i
fmt.Println(real(x*y)) //-5
fmt.Printlc(imag(x*y)) //10

如果在浮点数或十进制整数后紧接着写字母i,它就变成了一个虚数,表示一个实部为0的复数。

四、布尔值

bool型的值或布尔值只有两种可能:真(true)和假(false)。if和for语句里的条件就是布尔值,比较操作符也能得出布尔值结果。一元操作符(!)表示逻辑取反,因此!true就是false。布尔表达式x == true相对冗长,我们总简化为x。

布尔值无法隐式转换成数值(0或1),反之也不行。

五、字符串

字符串是不可变的字节序列,它可以包含任意数据。内置的len函数返回字符串的字节数,下标可以访问获取字符:

s := "hello, world"
fmt.Println(len(s)) //12
fmt.Println(s[0], s[7]) //104(h) 119(w)

试图访问范围之外的字节会出发宕机异常。

字符串的第i个字节不一定就是第i个字符,非ASCII字符和UTF-8码点需要两个或多个字节。

s[i:j]会产生一个新的字符串,内容取自原字符串中的字节,下标从i开始,直到j(左闭右开)。

fmt.Println(s[:5]) //hello
fmt.Println(s[7:]) //world
fmt.Println(s[:]) //hello, world

加号运算符连接两个字符串而生成一个新字符串:

fmt.Println("goodbye" + s[5:]) //goodbye, world

字符串也可以通过比较运算符进行比较,比较运算按字节进行,结果服从本身的字典排序。虽然可以将新值赋予字符串变量,但字符串的值无法被改变,即字符串内部的数据不允许修改。不可变意味着两个字符串能安全地公用同一段底层内存。

1.字符串字面量

字符串的值可以直接写成字符串字面量,形式上就是带双引号的字节序列:“Hello, 世界”。在带双引号的字符串字面量中,转义序列以反斜杠(\)开始,可以将任意值的字节插入字符串中:

\a “警告”或响铃

\b 退格符

\f 换页符

\n 换行符(直接跳到下一行的同一位置)

\r 回车符(返回行首)

\t 制表符

\v 垂直制表符

\’ 单引号(仅用于文字字符字面量’\’’)

\" 双引号(仅用于"……"字面量内部)

\\ 反斜杠

2.Unicode

Unicode囊括了世界上所有文书体系的全部字符,还有重音符和其他变音符,控制码(如制表符和回车符),以及许多特有文字。

3.UTF-8

UTF-8以字节为单位对Unicode码点作变长编码。每个文字符号用1-4个字节表示,ASCII字符的编码仅占1个字节,其他常用文书字符的编码是2或3个字节。一个文字符号编码的首字节的高位指明了后面还有多少字节。

4.字符串和字节slice

4个标准包对字符串的操作特别重要:

strings包:用于搜索、替换、比较、修整、切分和连接字符串

bytes包:用于操作字节slice([]byte类型,其某些属性和字符串相同)

strconv包:用于转换布尔、整数、浮点数为与之对应的字符串类型,反之也可以,还有为字符串添加/去除引号的函数

unicode包:有判别文字符号值特性的函数,如IsDigit、IsLetter、IsUpper和IsLower,每个函数以单个文字符号值作为参数,并返回布尔值

若字符串包含一个字节数组,撞见后就无法改变,相反,字节slice元素可以任意改变。字符串可以和字节slice相互转换:

s := "abc"
b := []byte(s) //元素可修改
s2 := string(b) //元素不可修改

[]byte(s)转换操作会分配新的字节数组,拷贝填入s含有的字节,并声称一个slice引用,指向整个数组。

5.字符串和数字的相互转换

除了字符串、文字符号和字节之间的转换,也常常需要字符串与数字之间的转化,这由strconv包的函数完成。

x := 123
y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv.Itoa(x)) //123 123
//FormatInt和FormatUint可以按不同的进制格式化数字
fmt.Println(strconv.FoematInt(int64(x), 2)) //1111011

六、常量

常量是一种表达式,可以保证在编译阶段就能计算出表达式的值。常量本质上属于基本类型。常量的声明定义了具名的值,看起来在语法上与变量类似,但该值恒定。与变量类似,同一个声明可以定义一系列常量。

对于常量操作数,所有数学运算、逻辑运算和比较运算的结果依然是常量,常量的类型转换结果和某些内置函数的返回值也同样是常量。常量声明可以同时指定类型和值,若没有显示指定类型,则类型根据右边表达式推断。

若同时声明一组常量,除了第一项外,其他项在等号右侧的表达式都可以省略,会复用前面意向的表达式及其类型。

const(
	a = 1
    b
    c = 2
    d
)
fmt.Println(a, b, c, d) //1 1 2 2

1.常量生成器iota

常量的声明可以使用常量生成器iota。它会创建一系列相关值,而不是逐个显示写出。常量声明中,iota从0开始取值,逐项加1。

type Weekday int
const(
	Sunday Weekday = iota //0
    Monday //1
    Tuesday //2
    Wednesday //3
    Thursday //4
    Friday //5
    Saturday //6
)

2.无类型常量

虽然常量可以是任何基本数据类型,但许多常量并不从属某一具体类型。从属类型待定的常量共有6种:无类型布尔、无类型整数、无类型文字符号、无类型浮点数、无类型复数、无类型字符串。它们的算数精度至少达到256位。

字面量的类型由语法决定。0、0.0、0i、和’\u0000’全都表示相同的常量值,但类型不同,分别是:无类型整数、无类型浮点数、无类型复数和无类型文字符号,true和false是无类型布尔值,字符串字面量是无类型字符串。

只有常量才可以是无类型的,若将无类型常量声明为变量,或在类型明确的变量赋值的右方出现无类型常量,则常量会被隐式转换为该变量的类型。

var f float64 = 3 + 0i //无类型复数->float64
f = 2 //无类型整数->float64
f = 1e123 //无类型浮点数->float64
f = 'a' //无类型文字符号->float64

不论显式或隐式,常量从一种类型转换成另一种,都要求目标类型能够表示原值。

变量声明中,加入没有显示指定类型,无类型常量会隐式转换成该变量的默认类型。

i := 0
r := '\000'
f := 0.0
c := 0i

Go语言中只有大小不明确的int类型,不存在大小不确定的float类型和complex类型。无类型整数可以转换成int,其大小不确定,但无类型浮点数和无类型复数可以被转换成大小明确的float64和complex128。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值