const
var
type
几个关键词的简单使用
package main
import "fmt"
// 定义常量
const (
P = 3.14
const1 = 1
const2 = "2"
const3 = 3
)
//全局变量的声明与赋值
var (
name = "james"
age = 18
name2 = "nihao"
)
// 一般类型的声明 type关键字
type (
newType int
type1 float32
type2 string
)
func main() {
fmt.Printf("Hello %s!\n", name) // Hello james!
}
重点理解第三个type关键词,已知这些类型,int,string等等,但是type可以声明自己的类型,这里newType属于一个新的类型,但是他的基础类型还是int,但跟int并不是同一个类型newType是他的命名
go基本类型
布尔型:bool
长度:1字节
取值范围:true、false
注意:不能像某些语言一样使用01数字来代表true或者false整型:int/uint
根据运行平台可能为32位(uint)或者64位(int)8位整型:int8/uint8
长度:1字节
取值范围:-128~127/0~255字节型:byte(uint8别名)
16位整型:int16/uint16
长度:2字节
取值范围:-32768~32767/0~6553532位整型:int32(rune)/uint32
长度:4字节
取值范围:(232/2~232/2-1)/(0~2^32-1)64位整型:int64/uint64
长度:8字节
取值范围:同理浮点型:float32/float64
长度:4/8字节
精准度:精确到7/15小数位复数:complex64/complex128
长度:8/16字节足够保存指针的32位或64位整数型:uintptr
其他值类型:
array、struct、string引用类型:
slice、map、chan接口类型:interface
函数类型:func
注意区分值类型和引用类型,会在后面变量传递的时候有区别
类型零值
零值并不等于空值,而是当变量被声明为某种类型后的默认值,就是说你在声明他的时候就存在值了,通常情况下值类型的默认值为0,比如int,就是一个0,slice就是多个或一个0,bool的默认值为false,string为空的字符串
package main
import "fmt"
func main() {
var a int
var b []int
var c string
var d bool
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}
/*
0
[]
false
*/
类型别名
// 一般类型的声明 type关键字
type (
newType int
type1 float32
type2 string
)
就是为类型起一个别名,注意的是基础类型与别名之后的类型并不完全对等,赋值等等需要转换
单个变量的声明与赋值
这个我刚看也有点愁人,声明和赋值的方法很多,并不是会简单好用的一种就够了,毕竟也要读别人的代码,所以必须全部掌握
第一种:声明-赋值
package main
import "fmt"
func main() {
// 声明 var-命名-类型
var a int
// 赋值
a = 111
fmt.Println(a) // 111
}
第二种:类型推断
package main
import "fmt"
func main() {
// 赋值并类型推断
var a = 111
fmt.Println(a) // 111
}
第三种:声明并赋值简单写法
package main
import "fmt"
func main() {
// 声明并赋值简单写法
a := 111
fmt.Println(a) // 111
}
这些方式不仅适用int等等这些类型的声明,也适用一些其他类型的声明,所以要掌握
系统推断的声明赋值前提是在使用过程中值的类型不会发生转变,否则会抛出错误
声明赋值变量要注意的点:
全局变量声明不能省略
var
关键字换成:=
来声明多个全局变量可以使用
var()
进行简写所有的变量都可以使用类型推断
局部变量不可以使用
var()
方式简写,只能使用并行方式
package main
import "fmt"
// 全局变量 支持多个变量赋值,支持并行,不可省略var
var (
a = "hello"
b = "hi"
aa, bb = 1, 2
)
func main() {
// 不可以使用括号,但是可以使用并行,可以省略var使用简写
var a, b, c, d int
a, b, c, d = 1, 2, 3, 4
// 也可以忽略赋值,只用_来代替变量名,可用于多返回值但是不需要全部返回值的时候
// 上面两句等价 var a, b, c, d int = 1, 2, 3, 4
e, f, g := 5, "ss", 6
fmt.Println(a, b, c, d, e, f, g)
}
变量的类型转换
- go中不存在隐式转换,所有类型转换必须显式声明
- 转换只能发生在两种相互兼容的类型之间
package main
import "fmt"
func main() {
var a float32 = 1.1
b := int(a)
fmt.Println(b) // 1
var c bool = true
d := int(c) // cannot convert c (type bool) to type int
}
要注意数字转字符串的时候会转为对应的字母,想要真正的转换成字符串需要库strconv
package main
import "fmt"
import "strconv"
func main() {
var a int = 65
b := string(a)
fmt.Println(b) // A
// int转string
c := strconv.Itoa(a)
fmt.Println(c) // 65
d, e := strconv.Atoi(c)
fmt.Println(d)
fmt.Println(e)
}
常量及运算符
常量的定义
- 常量的值在编译时就已经确认
- 常量定义格式与变量基本相同
- 等号右侧必须是常量或者常量表达式(必须是常量,不能是运行中产生的)
- 常量表达式中的函数必须是内置函数(自己写的函数不可以)
-
++
--
作为语句并不作为表达式 即不能放在等号右边
package main
import "fmt"
const a int = 2
const b = "A"
const (
c = a + 1
d = a * 3
// 没有表达式或者常量的话会自动选择上一行的表达式,前提是这两行格式相同
e
f, g = 22, 33
)
func main() {
fmt.Println(a) // 2
fmt.Println(b) // A
fmt.Println(c) // 3
fmt.Println(d) // 6
fmt.Println(e) // 6
fmt.Println(f) // 22
fmt.Println(g) // 33
}
常量的初始化规则与枚举
- 在定义常量组时,如果不提供初始值,则表示将使用上行的表达式
- 使用相同的表达式不代表具有相同的值
-
iota
是常量的计数器,从0开始,组中每定义一个常量自动递增1 - 通过初始化规则与
iota
可以达到枚举的效果 - 每遇到一个
const
关键字,iota就会重置为0
package main
import "fmt"
const (
// 使用双引号是会输出字符串A,单引号输出对应的数字
a = 'A'
b
// 此时iota为2
c = iota
d
)
const (
// 新的关键词const iota从0开始
e = iota
)
func main() {
fmt.Println(a) // 65
fmt.Println(b) // 65
fmt.Println(c) // 2
fmt.Println(d) // 3
fmt.Println(e) // 0
}
枚举应用
package main
import (
"fmt"
)
const (
a = 0
Monday = iota
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
)
func main() {
fmt.Println(Sunday) // 7
}
运算符
- go语言中运算符同样遵循从左至右的运算顺序
- 优先级(从高到低)
^ !
(一元运算)
* / % << >> & &^
+ - | ^
(二元运算)
== != < <= >=
<-
(专用与channel)
&&
||
新接触:
>> <<
左移/右移多少位
& | ^ &^
四个位运算符
/*
6: 0110
11: 1011
---------
两个数位运算先转换为2进制
& 0010 = 2 和
| 1111 = 15 或
^ 1101 = 13 对比过程中只存在一个1则为1
&^ 0100 = 4 如果第二个数对应的位置为1,则将第一个数对应的位置转换为0
之后再转换回10进制
*/
func main() {
fmt.Println(6 & 11) // 2
fmt.Println(6 | 11) // 5
fmt.Println(6 ^ 11) // 13
fmt.Println(6 &^ 11) // 4
}
单个的&变为了位运算符,&&作为‘与’运算符,左边条件不成立则右边不执行
实现计算机存储单位的枚举
const (
B float64 = 1 << (iota * 10)
KB
MB
GB
TB
)
func main() {
fmt.Println(B) // 1
fmt.Println(KB) // 1024
fmt.Println(MB) // 1.048576e+06
fmt.Println(GB) // 1.073741824e+09
fmt.Println(TB) // 1.099511627776e+12
}
指针
指针属于要深入了解的东西,
go虽然保留了指针,但是在go中并不支持指针运算以及
->
运算符,而是采用.
选择符来操作指针目标对象成员操作符
&
取变量地址,使用*
通过指针间接访问目标对象默认值为nil非NULL
package main
import (
"fmt"
)
func main() {
a := 1
// 声明指向int的指针p
var p *int
// 赋值p
p = &a
fmt.Println(p) // 0xc420014100
fmt.Println(&a) // 0xc420014100
fmt.Println(a) // 1
}