本文仅用于个人学习记录,只记录本人易忘知识点,内容并不完整
一、数据类型
1.变量声明未赋值时的默认值
数据类型 | 默认值 |
---|---|
数值类型(包括complex64/128等) | 0 |
bool | false |
字符串 | “”(空字符串) |
*int []int map[string] int chan int func(string) int error | nil |
2.变量声明方式
var intVal int
intVal = 1
或
intVal := 1
3.unsafe.Sizeof()返回的是变量的数据类型大小
4.特殊运算符
运算符 | 描述 | 作用 | 示例 |
---|---|---|---|
& | 返回变量存储地址 | 取变量对应的地址 | &a : 将给出变量的实际地址 |
* | 指针变量 | 取指针对应的值 | *a : 是一个指针变量 |
5.数组
声明数组
// 语法格式
// var variable_name [SIZE] variable_type
// 例子:
var balance [10] float32
初始化数组
// 长度确定
var balance= [5]float32{100.0, 2.0, 3.4, 7.0, 4.5}
balance := [5]float32{100.0, 2.0, 3.4, 7.0, 4.5}
// 长度确定 可通过下标初始化
balance := [5]float32{1:2.0,3:7.0}
//长度不定 可以用...代替数组长度
var balance= [...]float32{100.0, 2.0, 3.4, 7.0, 4.5}
balance := [...]float32{100.0, 2.0, 3.4, 7.0, 4.5}
二维数组
// 二维数组声明
a := [3][4]int{
{0, 1, 2, 3} , /* 第一行索引为 0 */
{4, 5, 6, 7} , /* 第二行索引为 1 */
{8, 9, 10, 11}, /* 第三行索引为 2 */
}
// 或者
sites := [2][2]string{}
sites[0][0] = "Google"
sites[0][1] = "Runoob"
sites[1][0] = "Taobao"
sites[1][1] = "Weibo"
// 长度不一的多维数组
animals := [][]string{}
row1 := []string{"fish", "shark", "eel"}
row2 := []string{"bird"}
row3 := []string{"lizard", "salamander"}
animals = append(animals, row1)
animals = append(animals, row2)
animals = append(animals, row3)
6.切片
可以理解为动态数组
声明一个未指定大小的切片
var identifier []type
创建指定长度的切片
var slice1 []type = make([]type, len)
slice1 := make([]type, len) // 不指定容量
slice1 := make([]type, len, capacity) // 指定容量
初始化
s :=[] int {1,2,3 }
s := arr[:] // arr是已经赋值完的数组
s := arr[startIndex:endIndex] // [startIndex, endIndex)前闭后开
函数
len(s) //切片的已经赋值的长度
cap(s) //切片的最大容量
append(s,1) // 向切片s中添加元素,如果容量不够则会扩容
copy(s1, s) //将s复制给s1
7.range
package main
import "fmt"
func main() {
//这是我们使用range去求一个slice的和。使用数组跟这个很类似
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
//在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。
for i, num := range nums {
if num == 3 {
fmt.Println("index:", i)
}
}
//range也可以用在map的键值对上。
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
//range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
for i, c := range "go" {
fmt.Println(i, c)
}
}
sum: 9
index: 1
a -> apple
b -> banana
0 103
1 111
8.map
var coun
tryCapitalMap map[string]string /*创建集合 */
countryCapitalMap = make(map[string]string)
/* map插入key - value对,各个国家对应的首都 */
countryCapitalMap [ "France" ] = "巴黎"
countryCapitalMap [ "Italy" ] = "罗马"
countryCapitalMap [ "Japan" ] = "东京"
countryCapitalMap [ "India " ] = "新德里"
9.并发
(1)go
使用关键字go开启goroutine
goroutine是轻量级线程
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
world
hello
hello
world
world
hello
hello
world
world
hello
(2)channel
channel用于两个goroutine之间传递数据
<-用于指定方向
ch <- v // 把 v 发送到通道 ch
v := <-ch // 从 ch 接收数据/并把值赋给 v
通道声明
ch := make(chan int)
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 把 sum 发送到通道 c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 从通道 c 中接收
fmt.Println(x, y, x+y)
}
-5 17 12
带缓冲的通道
ch := make(chan int, 100)
带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。
不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。
注意:如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。
go遍历通道和关闭通道
//遍历
v, ok := <-ch