go 的一些例子
go 的 switch–case
switch–case 走的逻辑 或者说流程 和 c/c++ 是一样的,自上而下,判断case 是否满足条件
如果满足条件,进入相应的语句,如果不满足,走 default
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Hello, 世界")
i := 5
fmt.Println("write ", i, " as ")
switch i {
case 1:
fmt.Print("one")
case 2:
fmt.Print("two")
case 3:
fmt.Print("three")
default:
fmt.Print("else")
}
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println(" this is weekend", time.Now().Weekday())
default:
fmt.Println(" this is weekday", time.Now().Weekday())
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("this is before noon", time.Now().Hour())
default:
fmt.Println("this is after noon", time.Now().Hour())
}
whatAmI := func(i interface{}) {
switch t := i.(type) {
case bool:
fmt.Println("this is a bool")
case int:
fmt.Println("this is a int")
case string:
fmt.Println("this is a string")
// 为什么 吧 default 写在最后?因为 t 会依次从bool 到 string 比较, 不满足当前的,就比较下一个,直到 default ,如果说 case 无穷, 如果一直没匹配到,那么这就是一个死循环了
default:
fmt.Println("Don't know this type", t)
}
}
whatAmI(true)
whatAmI(123)
whatAmI("zhangbuda")
whatAmI(2.22)
}
# 输出结果
Hello, 世界
write 5 as
else this is weekday Tuesday
this is after noon 23
this is a bool
this is a int
this is a string
Don't know this type 2.22
这里插播一下 关于 go 获取当前时间
import {
"time"
}
func main(){
// 如果要按照 年-月-日 小时:分钟:秒 格式获取当前时间,这个格式就写死了(可以试试)
// "2006-01-02 15:04:05" 网上说,这是go 诞生的时间 有点奇葩
fmt.Println("current time is ", now.Format("2006-01-02 15:04:05"))
//当然,也可以先获取时间戳,分别是秒和纳秒
currentUnixNanoTimestamp := time.Now().UnixNano()
seconds := currentUnixNanoTimestamp / int64(time.Second)
nanoseconds := currentUnixNanoTimestamp % int64(time.Second)
//将 秒时间戳 纳秒时间戳 放入函数 time.Unix
t := time.Unix(seconds, nanoseconds)
fmt.Println("Converted time:", t)
}
然后上面还写了一个匿名函数,没错!是go 的匿名函数,等下我还会让它和c++11的匿名函数做一个对比
// 定义匿名函数 whatAmI
//它接受一个空接口类
whatAmI := func(i interface{}){
...
// 这里用了类型断言
case t := i.(type)
}
// 如果匿名函数 有返回值
add := func(x, y int) int{
return x + y
}
result := add(1, 2)
fmt.Printf("1 + 2 = %d", result)
#include <iostream>
// 对了 go 的主函数是没有不能有参数的
// [] 捕获变量
// [var] 按值播火变量var
// [=] 按值捕获外部作用域中所有可见变量
// [&var] 按照引用捕获
// [&] 按照捕获外部作用域中所有可见变量
// ->int 匿名函数返回类型
int main(){
auto add = [](int x, int y)->int {
return x + y;
};
int result = add(1, 2);
std::cout<<result<<std::endl;
return 0;
}
[] //未定义变量.试图在Lambda内使用任何外部变量都是错误的.
[x, &y] //x 按值捕获, y 按引用捕获.
[&] //用到的任何外部变量都隐式按引用捕获
[=] //用到的任何外部变量都隐式按值捕获
[&, x] //x显式地按值捕获. 其它变量按引用捕获
[=, &z] //z按引用捕获. 其它变量按值捕获
参考01匿名函数
go 的数组
// 定义一个空的int 类型 长度为5 的一维 数组 默认全为0
// 如果采用 var a[5] int 定义 数组 会默认初始化
// 如果采用了 a:= [5]int {} 定义 数组 就需要添加 {}
// 二维三维 类推
// 总体来说,数组 都大差不差
var a [5]int
fmt.Println("emp:", a)
a[3] = 100
fmt.Println("a:", a)
fmt.Println("a[3]= ", a[3])
fmt.Println("a the len is ", len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println("dcl: ", b)
c := [2][3]int{}
fmt.Println("2d: ", c)
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
c[i][j] = i + j
}
}
fmt.Println("the c 2d is ", c)
d := [3][4][5]int{{}}
for i := 0; i < 3; i++ {
for j := 0; j < 4; j++ {
for k := 0; k < 5; k++ {
d[i][j][k] = i + j + k
}
}
}
fmt.Println("the d 3d is ", d)
# 执行结果
emp: [0 0 0 0 0]
a: [0 0 0 100 0]
a[3]= 100
a the len is 5
dcl: [1 2 3 4 5]
2d: [[0 0 0] [0 0 0]]
the c 2d is [[0 1 2] [1 2 3]]
the d 3d is [[[0 1 2 3 4] [1 2 3 4 5] [2 3 4 5 6] [3 4 5 6 7]] [[1 2 3 4 5] [2 3 4 5 6] [3 4 5 6 7] [4 5 6 7 8]] [[2 3 4 5 6] [3 4 5 6 7] [4 5 6 7 8] [5 6 7 8 9]]]
go 的切片 让我想起了 python 的切片
注意啊! c/c++ 中是没有切片这一个说法的,
对切片的介绍就是,有的场景使用切片会比使用数组更便捷
中间插播一条哈 就是在go 中可以看到很多 c/c++的风格 比如定义未使用
在 go 中会出现 如果导入包,但是未使用 的报错
留一个思考,go 中len 和cap 的区别是什么?
//开始切片
// s[x:y] 从 x 开始,到 y 结束,不包括 y 简言之 左关右闭
l := s[1:2]
l2 := s[1:]
fmt.Println("l: ", l, l == nil, len(l), cap(l))
fmt.Println("l2: ", l2, l2 == nil, len(l2), cap(l2))
// make
twoD := make([][]int, 3)
for i := 0; i < 3; i++ {
innerLen := i + 1
twoD[i] = make([]int, innerLen)
for j := 0; j < innerLen; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
# 运行结果
l: [b] false 1 5
l2: [b c f g h] false 5 5
2d: [[0] [1 2] [2 3 4]]
range
为什么有一种学python 的feeling
nums := []int{1, 2, 3, 4, 5}
sum := 0
sum2 := 0
// _ 表示忽略第一个返回值 go 的一个关键字 _ 用于忽略返回值 空白标识符
// 第一个返回值是索引,第二个返回值是元素
for _, num := range nums {
sum2 += num
}
fmt.Println("sum2: ", sum2)
for x, num := range nums {
sum += num
fmt.Println("index: ", x, "num: ", num)
}
fmt.Println("sum: ", sum)
# 运行结果
sum2: 15
index: 0 num: 1
index: 1 num: 2
index: 2 num: 3
index: 3 num: 4
index: 4 num: 5
sum: 15
map
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Println("key:", k, "value: ", v)
}
for k := range kvs {
fmt.Println("key:", k)
}
for _, v := range kvs {
fmt.Println("value:", v)
}
# 运行结果
key: a value: apple
key: b value: banana
key: a
key: b
value: apple
value: banana
function
func a1(a int, b int) int {
return a + b
}
其实 和c++11 的匿名函数是一个道理