数组
同一种数据类型元素的集合。数组的长度是数组类型的一部分
var a [3]int
数组的初始化(如果不初始化,默认元素都是零值)
// 1
a1 = [3]bool{true, true, true}
// 2 根据初始值自动推断
a2 = [...]int{1,2,3,4,5,6,7,8,9}
// 3 根据索引初始化
a3 := [5]int{0:1, 4:2}
数组的遍历
citys := [...]string{"上海""深圳""广州"}
// 索引编译
for i:=0;i<len(citys);i++{
fmt.Println(citys[i])
}
// for range
for i, v := range citys {
}
多维数组
// [[1 2] [3 4] [5 6]]
var a11 [3][2]int
a11 = [3][2]int {
[2]int {1,2},
[2]int {3,4},
[2]int {5,6},
}
多维数组的遍历
for _, v1 := range a11 {
for _, v2 := range v1 {
}
}
数组是值类型,赋值时总是创建了新的地址
b1 := [3]int {1,2,3}
b2 := b1 // 赋值时创建是创建了新的地址,并放入,修改b2不影响b1
b2[0] = 100
数组支持
==
!=
, 因为内存总是被初始化过的[n]T表示指针数组, [n]T 表示数组指针
切片
Go 语言中的切片有三种初始化的方式:
- 通过下标的方式获得数组或者切片的一部分;
- 使用字面量初始化新的切片;
- 使用关键字
make
创建切片:arr[0:3] or slice[0:3]
slice := []int{1, 2, 3}
slice := make([]int, 10)
切片是引用类型,不支持直接比较,只能和nil比较。切片的本质就是一个框,框住了一块连续的内存,属于引用类型,真正的数据都是来自于底层数组。
// 与nil 比较
t == nil
切片拥有自己的长度和容量,可以通过len()
求长度,使用内置的cap()
求切片的容量
可以使用append
方法来为切片添加元素,索引不能超过容量,否则会产生越界错误.使用append
相当于创建了一块新的内存给切片。(底层数组变了,即地址变了)
a3 = append(a3, 111)
使用**copy**
来复制切片,会划分一块新的地址。简单的赋值只是做了地址引用,而使用copy
则是划分了新的地址给它
a1 := []int{1,3,5}
a2 := a1
var 3 make([]int, 0, 3)
copy(a3, a1)
切片没有删除的专用方法,需要使用切片的本身特性来删除。 …运算符表示将一个切片的所有元素追加到另一个切片里
a := []int{1,2,3,4}
// 删除索引为2的元素
a = append(a[:2], a[3:]...)
字典(哈希表)
go语言中提供映射关系,无序的,是引用类型(需要初始化)
var a map[string]int
a = make(map[string]int, 0) // 自动扩容
a["1"] = 1
value, ok := a["1"] // 约定俗称使用ok接收返回的布尔值
// 使用key value来表示键值对
hash := map[string]int{
"1": 2,
"3": 4,
"5": 6,
}
遍历
for k,v := range a {}
// 只遍历key
for k := range a {}
// 只遍历value
for _,v := range a {}
删除
delete(a,"1")
map和slice的组合: 要初始化
- 元素为map类型的切片
var s1 = make([]map[int]string, 0, 10) //初始化slice,访问第一个元素报越界错误
var s2 = make([]map[int]string, 1, 10) //初始化slice,访问第一个元素报未初始化map错误
s1[0] = make(map[int]string, 1)
s1[0][100] = "abc"
- 值为切片类型的map
var m1 = make(map[string][]int, 10)
m1['北京'] = []int{10, 20, 30}
字符串
utf-8。
go语言中的双引号只能用双引号。go语言中的单引号包裹的是字符。
字符:’h’ ‘你’ ,单独的字母,汉字,符号表示一个字符。
一个AscII等于一个字节(8位)
一个utf8编码的汉字等于3个字节
多行字符串
s2=`123
456
789
`
字符串常用操作
- len(str)
+
或fmt.Sprintf
- strings.Split 分割
- strings.contains 包含
- strings.HasPrefix, strings.HasSuffix 前缀/后缀判断
- strings.Index(), strings.LastIndex() 子串出现的位置
- strings.Join(a[]string, sep string) join操作
流程控制
if
if age > 18 {
} else if {
} else {
}
作用域
if age := 19; age >18 { //age只在if条件判断中生效
} else {
}
不支持三元操作符(三目运算符) > a > b ? a : b
。
switch
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止。 Golang switch 分支表达式可以是任意类型,不限于常量。可省略 break,默认自动终止。
switch var1 {
case val1:
...
case val2:
...
default:
...
}
switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。
switch x.(type){
case type:
statement(s)
case type:
statement(s)
/* 你可以定义任意个数的case */
default: /* 可选 */
statement(s)
}
select
select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。
select 是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。 select 随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。
select {
case communication clause :
statement(s);
case communication clause :
statement(s);
/* 你可以定义任意数量的 case */
default : /* 可选 */
statement(s);
}
使用场景:
- 超时判断
```go
var resChan = make(chan int)
// do request
func test() {
select {
case data := <-resChan:
case <-time.After(time.Second * 3):doData(data)
} }fmt.Println("request time out")
func doData(data int) { //… }
2. 退出
```go
//主线程(协程)中如下:
var shouldQuit=make(chan struct{})
fun main(){
{
//loop
}
//...out of the loop
select {
case <-c.shouldQuit:
cleanUp()
return
default:
}
//...
}
//再另外一个协程中,如果运行遇到非法操作或不可处理的错误,就向shouldQuit发送数据通知程序停止运行
close(shouldQuit)
- 判断是否阻塞 ```go //在某些情况下是存在不希望channel缓存满了的需求的,可以用如下方法判断 ch := make (chan int, 5) //… data:=0 select { case ch <- data: default: //做相应操作,比如丢弃data。视需求而定 }
<a name="kAeeG"></a>
## for
```go
for i :=0;i<10;i++{
}
可以省略初始语句
for ;i<10:i++{
}
可以省略执行语句
for i < 10{
i++
}
无限循环
for {
}
for range:遍历数组,切片,字符串,map及通道
s := "hello"
for i, v := range s {
fmt.Printf("%d %c\n", i, v)
}
跳出循环break
跳出指定循环
package main
import (
"fmt"
)
func main() {
J:
for j := 0; j < 5; j++ {
for i := 0; i < 10; i++ {
if i > 6 {
break J //现在终止的是j 循环,而不是i的那个
}
fmt.Println(i)
}
}
}
跳过continue