当前位置:网站首页>【Go基础】2 - Go基本语句
【Go基础】2 - Go基本语句
2022-07-04 07:40:00 【李易安QSR】
目录
一、Go语言的数据类型
数据类型完全不能隐式转换
如:
var a int32 = 1
var b int64 = 2
a = b
- 指针类型
- 不支持指针运算
- string是值类型,其默认的初始化值为空字符串,不是nil
package main
import "testing"
func TestOne(t *testing.T) {
//指针
a := 1
aPtr := &a
t.Log(a,aPtr)
t.Logf("%T %T",a,aPtr)
//指针不允许指针运算
//aPtr += 1
var s string //默认初始化是 “”,不是nil
t.Log("*" + s + "*")
}
二、运算符
三、循环和条件
1、循环
go只支持for
package class01
import "testing"
//for循环的讲解
/* go语言中只支持for循环 */
//如何编写一个有限循环
func TestOne5_1(t *testing.T) {
n := 0
for n < 5 {
n++
t.Log(n)
}
}
//如何编写一个无限循环
func TestOne5_2(t *testing.T) {
n := 0
for {
t.Log(n)
}
//如何break呢?
//for {
// t.Log(n)
// if n == 10 {
// break
// }
// n++
//}
}
2、if
package class01
import "testing"
//如何写一个条件
func TestOne6_1(t *testing.T) {
n := 0
if n == 1 {
t.Log("n输入了1")
} else if n == 0 {
t.Log("n输入了0")
} else {
t.Log("n不知道输入了什么")
}
//与其他语言不同的地方是 条件必须是bool类型,不允许是整型或字符型,因为不存在隐式转换
/* if 1 { } */
}
- case后边默认加了有break,因此go里边不需要
- case后边可以加多个case,命中的都可以进
package class01
import "testing"
func TestOne7_1(t *testing.T) {
n := 0
switch n {
//第二种写法
//switch n := 0 n {
case 0, 1:
t.Log("memexixi")
case 2, 3, 4:
t.Log("halouhalou")
default:
t.Log("*********")
}
}
/*总结: 1、switch中可以后边跟一个赋值表达式,如函数等,再跟一个要判断的变量 2、默认每个case后边都有break,不需要再次添加 */
四、数组和切片
package class01
import "testing"
//数组的声明
func TestOne8_1(t *testing.T) {
var a [3]int
a[0] = 1 //下标也是从0开始
t.Log(a[0]) //打印刚才的赋值
t.Log(a[1]) //查看没有赋值的部分,发现并不会报错,int类型 会给出默认值0
n := 3
//t.Log(a[3]) //直接写会报错
t.Log(a[n]) //直接检查就会报错,不允许访问越界
//那字符串类型会给出什么默认值呢?
var b [3]string
t.Log(b[0]) //给出了默认值""
//数组的第二种声明方式
c := [3]int{
1, 2, 3}
t.Log(c[0])
//多维数组的声明方式
//d := [2][2]int{1, 2, 3, 4} //不允许像c中这样
d := [2][2]int{
{
1, 2}, {
3, 4}}
t.Log(d[0])
//不定数组长度的声明方式
e := [...]int{
1, 2, 3, 4, 5}
t.Log(e[3])
}
//数组的遍历
func TestOne8_2(t *testing.T) {
arr := [...]int{
1, 2, 3, 4, 5}
//传统的遍历方式
for i := 0; i < len(arr); i++ {
//{ 强制代码格式,如果写到下一行会报错,expected '{', found newline
t.Log(arr[i])
}
}
func TestOne8_3(t *testing.T) {
arr := [...]int{
1, 2, 3, 4, 5}
//range遍历
for index, item := range arr {
t.Logf("第%d个元素是%d", index, item) //格式化输入输出,跟c一样
}
//我们常常并不关注这个index的值,但是range又返回了两个,我们可以通过_进行接收
for _, item1 := range arr {
t.Log(item1)
}
}
数组内部
- 指针
- 元素个数
- 内部数组的容量
package class01
import "testing"
//数组的截取
func TestOne9_1(t *testing.T) {
//总结就是前包含,后不包含
a := [...]int{
0, 1, 2, 3, 4, 5}
t.Log(a[1:2]) //[1]
t.Log(a[1:3]) //[1 2]
t.Log(a[1:len(a)]) //[1 2 3 4 5]
t.Log(a[1:]) //不写默认为 len(a) [1 2 3 4 5]
t.Log(a[:3]) //不写默认为0 [0 1 2]
//不允许有-1,那种骚东西
//t.Log(a[0:-1])
/* 切片总结: 1、内部实现的本质是一个结构体,包含三个属性 - 数组指针ptr - 数据个数len(int) - 内部数组的容量cap (int) */
}
//如何声明一个切片呢?
func TestOne9_2(t *testing.T) {
var sl []int //这样不声明长度,就是一个切片,它就是 可变长
t.Log(len(sl), cap(sl))
sl = append(sl, 1)
t.Log(len(sl), cap(sl))
sl = append(sl, 2, 3)
t.Log(len(sl), cap(sl))
s2 := []int{
1, 2, 3, 4}
t.Log(len(s2), cap(s2))
s3 := make([]int, 3, 5)
t.Log(len(s3), cap(s3))
t.Log(s3[0], s3[1], s3[2])
//t.Log(s3[0], s3[1], s3[2], s3[3], s3[4]) //最后2个报错,告诉我们下标越界
//因此,cap表示的是整个容量,len表示当前可用的范围
}
//测试切片的增长
func TestOne9_3(t *testing.T) {
s := []int{
}
for i := 0; i < 10; i++ {
s = append(s, i)
t.Log(len(s), cap(s))
}
//Java的vector相似,容量不够的时候自动拓展,并且是x2增长
}
//切片共享内存的理解
func TestOne9_4(t *testing.T) {
arr := [10]int{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice1 := arr[:5]
slice2 := arr[3:]
t.Log(slice1)
t.Log(slice2)
//如果我修改了原始数组arr的arr[3],两个切片的内容也会跟着修改,本质上还是需要了解切片的底层实现
arr[3] = 11
t.Log(slice1)
t.Log(slice2)
}
五、Map的声明、元素访问和遍历
package class01
import (
"testing"
)
//map的声明
func TestOne10_1(t *testing.T) {
var myMap1 map[string]string //只是声明没有开辟空间
if myMap1 == nil {
t.Log("myMap1 是一个空map")
}
myMap1 = make(map[string]string, 10)
myMap1["one"] = "java"
myMap1["one1"] = "java1"
myMap1["one2"] = "java2"
myMap1["one3"] = "java3"
myMap1["one4"] = "java4"
t.Log(myMap1)
t.Log(myMap1["one3"])
//第二种方式 使用make函数进行声明
myMap2 := make(map[int]string)
myMap2[1] = "java"
myMap2[2] = "java2"
myMap2[3] = "java3"
myMap2[4] = "java4"
t.Log(myMap2)
t.Log(len(myMap2))
//第三种方式
myMap3 := map[string]string{
"one": "php",
"two": "java",
"three": "python",
}
t.Log(myMap3)
t.Logf("myMap3的长度是%d", len(myMap3))
//问:为什么map不需要初始化len?只需要cap?
}
//map常用操作
func TestOne10_2(t *testing.T) {
var myMap1 map[int]int
var myMap2 map[string]string
t.Log(myMap1[0]) //0
t.Log(myMap2["no"]) //""
//我们发现go会给我们一个map的默认值,如果不存在这个key的话,那如果我真的存了一个0或""呢?如何判断?
//其实go语言中的map取值,m[0]是返回了两个变量,第一个是value,第二个是bool,存在为true,不存在是false
if v, exist := myMap1[0]; exist {
//如果存在就打印这个值
t.Log(v)
} else {
t.Log("这个key不存在")
}
//myMap1[2] = 0
//t.Log(myMap1[2]) //会报错,因为myMap1只是声明,没有开辟控件
myMap1 = make(map[int]int)
myMap1[2] = 0
t.Log(myMap1[2])
delete(myMap1, 2) //删除操作
}
//map的遍历
func TestOne10_3(t *testing.T) {
myMap3 := map[string]string{
"one": "go",
"two": "java",
"three": "python",
}
for k, v := range myMap3 {
t.Logf("key是%s,value是%s", k, v)
}
}
package main
import "fmt"
func printMap(cityMap map[string]string) {
//map传递就是 本质也是值传递,原因是结构被复制,结构内部的指针没有变化,看起来像是引用传递
for s, s2 := range cityMap {
fmt.Println("key = ",s)
fmt.Println("value = ",s2)
}
}
func main() {
cityMap := make(map[string]string)
//添加
cityMap["china"] = "beijing"
cityMap["amaircan"] = "niuyue"
cityMap["japan"] = "tokyo"
//遍历
printMap(cityMap)
//当map中获取一个值不存在的时候,会返回默认值0
//删除
delete(cityMap,"china")
//修改
cityMap["amaircan"] = "henan"
fmt.Println("----------")
//遍历
for key, value := range cityMap {
fmt.Println("key = ",key)
fmt.Println("value = ",value)
}
}
六、在Go中实现Set集合
Go中没有Set,但是可以map[type] bool
就是用键当做存储单元,内部的值当做是否有效的标记
package class01
import "testing"
func TestOne11_1(t *testing.T) {
//go语言中没有原生支持set,是通过map的变形操作制作 使用map[type] bool
set1 := map[string]bool{
}
//新增的方式
set1["qsr"] = true
set1["wxy"] = true
//删除的方式
set1["qsr"] = false
//本质上就是通过map的key唯一来进行实现的
}
//顺带说一下,Map与工厂模式的实现
func TestOne11_2(t *testing.T) {
m := map[int]func(op int) int{
} //定义一个map,key是int,value是一个函数func,这个函数的参数是op int类型,返回值是int
m[1] = func(op int) int {
return op }
m[2] = func(op int) int {
return op * op }
m[3] = func(op int) int {
return op * op * op }
t.Log(m[1](2), m[2](2), m[3](2))
}
七、字符串
package class01
import "testing"
func TestOne12_1(t *testing.T) {
var s string
t.Log(s)
s = "hello"
t.Log(len(s))
//s[1] = '3' //go中,string是不可变的,原因是string类型的实现方式本质上是byte类型的slice
s = "\xE4\xB8\xA5" //可以存储任何二进制数据
t.Log(s)
t.Log(len(s)) //输出的是byte数,并非是简单的中文*2的长度
}
func TestOne12_2(t *testing.T) {
//对比Unicode和UTF8的区别
s1 := "中"
t.Log(len(s1))
c := []rune(s1)
t.Log(len(c))
t.Logf("中 的Unicode %x", c[0])
t.Logf("中 的UTF8 %x", s1)
/* Unicode是一种编码规则 UTF8是存储规则 */
}
//字符串的遍历
func TestOne12_3(t *testing.T) {
s := "中华人民共和国"
for _, c := range s {
t.Log(c)
t.Logf("%[1]c %[1]x %[1]d", c) // %[1] 表示都跟第一个参数对应
}
}
- 常用的字符串库
package class01
import (
"strconv"
"strings"
"testing"
)
//字符串分割 和 合并
func TestOne13_1(t *testing.T) {
s := "a:b:c"
parts := strings.Split(s, ":")
for _, ch := range parts {
t.Log(ch)
}
t.Log(strings.Join(parts, "-"))
}
//字符串类型转换
func TestOne13_2(t *testing.T) {
//将数字强制转换为string类型
s := strconv.Itoa(10)
t.Log("str:" + s) //字符串之间可以直接+
//将string类型强制转换为int
if n, err := strconv.Atoi("10"); err == nil {
t.Log(n)
}
}
八、函数
1、函数式编程
package class01
import (
"fmt"
"math/rand"
"testing"
"time"
)
//多返回值的函数
func returnMuliValues() (int, int) {
return rand.Intn(10), rand.Intn(20)
}
func TestOne14_1(t *testing.T) {
a, b := returnMuliValues()
t.Log(a, b)
a, _ = returnMuliValues()
t.Log(a)
}
//计算方法时长,装饰器的使用
func timeSpent(inner func(op int) int) func(op int) int {
//声明一个入参是函数,返回值也是一个函数的方法
return func(n int) int {
start := time.Now()
ret := inner(n) //相当于将入参中的函数放在中间执行
fmt.Println("函数执行总时间花费", time.Since(start).Seconds())
return ret
}
}
func slowFun(op int) int {
time.Sleep(time.Second * 1)
return op * 3
}
func TestOne14_2(t *testing.T) {
res := timeSpent(slowFun) //res函数,就是装饰之后的函数,返回值还是保留了原来的值,当然也可以进行改动
t.Log(res(3))
}
2、可变参数 和 defer的用法
都会转化为数组,最终通过数组遍历来实现
- defer:无论如何都会最后执行一下的
可以用作安全的释放资源,释放锁等
package class01
import (
"fmt"
"testing"
)
//可变参数的函数
func Sum(ops ...int) int {
resu := 0
for _, v := range ops {
resu += v
}
return resu
}
func TestOne15_1(t *testing.T) {
t.Log(Sum(1, 2, 3))
t.Log(Sum(1, 2, 3, 4, 5))
}
//defer的用法
func DeferDemo() {
fmt.Println("执行了defer")
}
func TestOne15_2(t *testing.T) {
defer DeferDemo()
fmt.Println("run now")
panic("e")
}
/* defer总结 1、一定会执行 2、一定是终止前执行 3、即使是panic崩溃也不会影响,类似于try catch中的finally,一定会执行 用处:安全的释放资源,释放锁等 */
边栏推荐
- [kubernetes series] kubesphere is installed on kubernetes
- [C language] open the door of C
- 时序数据库 InfluxDB 2.2 初探
- MYCAT middleware installation and use
- JVM -- class loading process and runtime data area
- Leetcode (215) -- the kth largest element in the array
- Would you like to go? Go! Don't hesitate if you like it
- Unity 从Inspector界面打开资源管理器选择并记录文件路径
- Amd RX 7000 Series graphics card product line exposure: two generations of core and process mix and match
- The frost peel off the purple dragon scale, and the xiariba people will talk about database SQL optimization and the principle of indexing (primary / secondary / clustered / non clustered)
猜你喜欢
Zabbix agent主动模式的实现
Zephyr study notes 2, scheduling
JVM中堆概念
What are the work contents of operation and maintenance engineers? Can you list it in detail?
Zephyr 學習筆記2,Scheduling
Transition technology from IPv4 to IPv6
果果带你写链表,小学生看了都说好
【Kubernetes系列】Kubernetes 上安装 KubeSphere
I was pressed for the draft, so let's talk about how long links can be as efficient as short links in the development of mobile terminals
Amd RX 7000 Series graphics card product line exposure: two generations of core and process mix and match
随机推荐
Basic DOS commands
墨者学院-phpMyAdmin后台文件包含分析溯源
MySQL中的文本處理函數整理,收藏速查
21个战略性目标实例,推动你的公司快速发展
Easy to understand: understand the time series database incluxdb
L1-022 odd even split (10 points)
Valentine's Day is coming! Without 50W bride price, my girlfriend was forcibly dragged away...
真空介电常数和真空磁导率究竟是由什么决定的?为何会存在这两个物理量?
如何用MOS管来实现电源防反接电路
How to reset IntelliSense in vs Code- How to reset intellisense in VS Code?
MySQL中的文本处理函数整理,收藏速查
Book list | as the technical support Party of the Winter Olympics, Alibaba cloud's technology is written in these books!
Rhcsa the next day
zabbix監控系統自定義監控內容
[web security] nodejs prototype chain pollution analysis
Zephyr 学习笔记1,threads
[untitled] notice on holding "2022 traditional fermented food and modern brewing technology"
When JDBC connects to es query, is there a God who meets the following situation?
The frost peel off the purple dragon scale, and the xiariba people will talk about database SQL optimization and the principle of indexing (primary / secondary / clustered / non clustered)
Zephyr Learning note 2, Scheduling