目录
一、变量和常量
高级语言通过一个标识符来绑定一块特定的内存,后续对特定内存的操作都可以使用该标识符来替代。这类绑定某个存储单元的标识符分为两类,一类称之为“变量”,一类称之为“常量”。变量表示指向的内存可以被修改,常量表示指向的内存不能被修改。
1.变量
使用一个名称来绑定一块内存地址,该内存地址中存放的数据类型有定义变量时指定的类型决定,该内存地址里面存放的内容可以改变。
1.1 显示的完整声明
var varName dataType [ = value]
*关键字var用于变量声明
*varName是变量名标识符
*dataType是基本类型,如int、string
*value 是变量的初始值,初始值可以使字面量,也可以是其他变量名,还可以是一个表达式;如果不指定初始值,Go会默认将该变量初始化为类型的零值。
1.2 短类型声明
varName := value
* := 声明只能出现在函数内(包括在方法内)
* 此时Go编译器自动进行数据类型推断
Go支持多个类型变量同时声明并赋值。例如:
a, b := 1, "hello"
变量具有以下几个属性:
*变量名
Go使用自定义标识符来声明一个变量。
*变量值
变量实际指向的是地址里存放的值,变量的值具体怎么解析是由变量的类型来决定的。在初始化变量值时,我们可以使用字面量,也可以使用其他的变量值
*变量存储和生存期
Go语言提供自动内存管理,通常程序员不需要特别关注变量的生存期和存放位置。编译器使用栈逃逸技术能够自动为变量分配空间:可能在栈上,也可能在堆上
*类型信息
类型决定了该变量存储的值怎么解析,以及支持哪些操作和运算,不同类型的变量支持的操作和运算集是不一样的
*可见性和作用域
Go内部使用统一的命名空间对变量进行管理,每个变量都有一个唯一的名字,包名是这个名字的前缀。
2 .常量
一旦定义了,就不能修改,常量使用一个名称来绑定一块内存地址,该内存地址中存放的数据类型由定义常量时指定的类型决定,而且该内存地址里面存放的内容不可以改变。
Go中常量分为布尔型、字符串型和数值型常量。常量存储在程序的只读段里。
//类似枚举的iota,iota 是一个特殊的常量,是常量计数器
const(
c0 = iota //c0 == 0
c1 = iota //c1 == 1
c2 = iota //c2 == 2
)
//简写模式
const(
c0 =iota //c0 == 0
c1 //c1 == 1
c2 //c2 == 2
)
//注意iota是逐行增加的
const(
a = 1 << iota //a == 1 (iota == 0)
b = 1 << iota //b == 2 (iota == 1)
c = 3 //c == 3 (iota == 2, unused)
//iota是一个常量生成器,它会在每次被调用时生成一个新的常量。d的值是1左移iota(即3),即1左移3,等于8
d = 1 << iota //d == 8 (iota == 3)
)
const(
u = iota * 42 //u == 0 (untyped integer constant)
v fluat64 = iota * 42 //v == 42.0 (float64 constant)
w = iota * 42 //w == 84 (untyped integer constant)
)
//分开的const语句,iota每次都从0开始
const x = iota //x == 0
const y = iota //y == 0
二、基本数据类型
Go是一种强类型的静态编译语言
Go语言内置七类基本数据类型:
布尔类型:bool
整型:byte int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr
浮点型:float32 float64
复数:complex64 complex128
字符:rune
字符串:string
错误类型:error
2.1 布尔类型
布尔类型关键字:bool,布尔类型只有两个值:true和false,true和false是Go内置的两个预声明标识符。
var ok bool
ok = true
或
ok := false
布尔类型数据和整型数据不能进行相互转换
var a bool
a = 1 //error 1是整型字面值
比较表达式和逻辑表达式的结果都是布尔类型数据
var b bool = (x > y) && (x > 0)
if和for语句的条件部分一定是布尔类型的值或表达式
if a <= b {
print(b)
}else{
print(a)
}
for ;true;( //等价于C语言的while (1)
)
声明的布尔型变量如不指定初始化值,则默认为false
var b bool // b is false
2.2 整型
Go语言内置了12种整数类型,分别是:byte int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr,不同类型的整型必须进行强制类型转换。
var a int = 1
var b int32 = 2
b = a // error
整数支持算数运算和位运算, 算数表达式和位操作表达式的结果还是整型
var a int = (1+2)*3
var b int = 1000>>2
2.3 浮点型
浮点型用于表示包含小数点的数据,Go语言内置两种浮点型,float32和float64
浮点数有两个注意事项:
(1) 浮点数字面值被自动类型推断为float64类型
var b := 10.00
(2)计算机很难进行浮点数的精确表示和存储,因此两个浮点数之间不应该使用 == 或 != 进行比较操作,高精度科学计算应该使用math标准库。
2.4 复数类型
Go语言内置的复数类型有两种,分别是complex64和complex128,复数在计算机里面使用两个浮点数表示,一个表示实部,一个表示虚部。complex64由两个float32构成,complex128是由两个float62构成的。复数的字面量表示和数学表示法一样。
var value1 complex64 = 3.1 + 5i
value2 := 3.1 + 6i
Go有三个内置函数处理复数
var v = complex(2.1, 3) //构造一个复数
a := real(v) //返回复数实部
b := image(v) //返回复数虚部
2.5 字符串
Go语言将字符串作为一种原生的基本数据类型,字符串的初始化可以使用字符串字面量,例如:
var a = "hello,world"
(1) 字符串是常量,可以通过类似数组的索引访问其字节单元,但是不能修改某个字节的值,例如:
var a = "hello,world"
b := a[0]
a[1]='a' //error
(2)字符串转换为切片[]byte(s)要慎用,尤其是当数据量较大时(没转换一次都需要复制内容).例如:
a := "hello,world!"
b := []byte(a)
(3)字符串尾部不包含NULL字符,这一点和C/C++不一样
(4)字符串类型底层实现是一个二元的数据类型,一个是指针指向字节数组的起点,另一个是长度。例如:
// runtime/string.go
type stringStruct struct(
str unsafe.Pointer //指向底层字节数组的指针
len int //字节数组长度
)
(5)基于字符串创建的切片和原字符串只想相同的底层字符数组,一样不能修改。对字符串的切片操作返回的字串仍然是string,而非slice。例如
a := "hello,world!"
b := a[0:4]
c := a[1:]
d := a[:4]
(6)字符串和切片的转换:字符串可以转换为字节数组,也可以转换为Unicode的字数组。例如:
a := "hello.世界!"
b := []byte(a)
c := []rune(a)
(7)字符串的运算。例如:
a := "hello"
b := "world"
c := a + b //字符串的拼接
len(a) //内置的len函数获取字符串长度
d := "hello,世界!"
for i := 0; i < len(d); i++{ //遍历字节数组
fmt.Println(d[i])
}
for i, v := range d{ //遍历rune数组
fmt.Println(i, v)
}