Go_day02
Go基础语法
流程控制
一共有三种:顺序结构,选择结构,循环结构
if语句
/*
if与else if的区别:
1:if无论是否满足条件都会向下执行,直到程序结束,else if 满足一个条件就会停止执行。
2:由于if都会执行一遍,则可能会同一个需要判断的事件,会进入2个if语句中,出现错误,而else if就不会发生这样的事情。
*/
func main() {
var a int = 15
var score int = 80
if a > 20 {
fmt.Println("a大于20")
}
if a > 10 {
fmt.Println("a大于10")
}
if score >= 90 && score <= 100 {
fmt.Println("A")
} else if score >= 80 && score < 90 {
fmt.Println("B")
} else if score >= 70 && score < 80 {
fmt.Println("C")
} else if score >= 60 && score < 70 {
fmt.Println("D")
} else {
fmt.Println("F")
}
}
if嵌套
// 通过if嵌套实现二次验证密码
func main() {
var a, b int
var pwd int = 20221108
fmt.Print("请输入密码:")
fmt.Scan(&a)
if a == pwd {
fmt.Print("请再次输入密码:")
fmt.Scan(&b)
if b == pwd {
fmt.Println("登录成功")
} else {
fmt.Println("登录失败,密码输入不一致")
}
} else {
fmt.Println("密码错误")
}
}
switch语句
// switch语句
func main() {
var score int = 90
//case来匹配 switch后的结果
switch score {
case 90:
fmt.Print("A")
fallthrough //通过此关键字实现穿透
case 80:
fmt.Print("B")
//由于每一个case自带break效果 只能穿透到这里 如果继续穿透 需要再添加fallthrough
fallthrough
case 70, 60, 50:
//如果想过提前结束可以添加break
if score == 80 {
break
}
fmt.Print("C")
default:
fmt.Print("D")
}
//switch的默认条件是 bool=ture
switch {
case false:
fmt.Print("false")
case true:
fmt.Print("true")
default:
fmt.Println("其他")
}
}
与java不同case后默认自带break效果 所以一般不存在穿透效果
所以需要使用fallthrough关键字来实现穿透效果
单独使用fallthrough会强制穿透,不管下一个case中的条件是否满足所以可以搭配break使用
for循环
func main() {
//循环10次
for i := 0; i < 10; i++ { //i的作用域只在for循环中哦
fmt.Println(i)
}
//计算从1到10的和
sum := 0
for i := 1; i <= 10; i++ {
sum += i
}
fmt.Println(sum)
j := 0
for j < 110 {
fmt.Println(j)
j++
}
}
for循环中的所有参数都可以省略有这么几种情况:
1、for :循环条件: 这样需要声明变量起始值 并在循环体中控制 变量的增减
2、for {} 这就是无限循环
练习
func main() {
//打印一个 5*5的星号方阵
fmt.Println("5*5的星号方阵哦")
for i := 1; i <= 5; i++ {
for i := 1; i <= 5; i++ {
fmt.Print(" *")
}
fmt.Println()
}
//打印九九乘法表
fmt.Println("九九乘法表")
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d*%d=%d/t", j, i, i*j)
}
fmt.Println()
}
//这样也是可行的 不过效率就降低了
for i := 1; i <= 9; i++ {
for j := 1; j <= 9; j++ {
if j > i {
break
}
fmt.Printf("%d*%d=%d/t", j, i, i*j)
}
fmt.Println()
}
}
break 与 continue
func main() {
//break是直接结束本循环程序
for i := 0; i < 10; i++ {
if i == 5 {
break
}
fmt.Println(i)
}
//continue跳过本次循环
for i := 0; i < 10; i++ {
if i == 5 {
continue
}
fmt.Println(i)
}
}
string
func main() {
str := "hello,my country"
fmt.Println(str)
//获取字符串的长度
fmt.Println("字符串的长度为:", len(str))
//获取字符串指定的字节
fmt.Println("字节打印:", str[2]) //acsii编码值108
fmt.Printf("%c\n", str[2])
//for循环遍历字符串
for i := 0; i < len(str); i++ {
fmt.Printf("%c", str[i])
}
for i, j := range str {//i 是字符串下标 j是字节
fmt.Print(i)
fmt.Printf("%c", j)
}
}
string中的字节不能被单独改变
函数
函数是基本的代码块 用于执行一个任务
func 函数名 (参数1,参数2,...)返回值类型 int,int,...{
函数体
return 返回结果
}
- 无参无返回值、几个或没有参及返回值
func main() {
fmt.Println(add(2, 3))
printinfo()
printinfo2("你好")
a, b := printinfo3("世界", "你好")
fmt.Println(a, b)
}
func printinfo() {
fmt.Println("我是无参无返回值")
}
func printinfo2(str string) {
fmt.Println("我是有参无返回值", str)
}
func printinfo3(str, st2 string) (string, string) {
return st2, str
}
func add(a, b int) int {
c := a + b
return c
}
可变参数
func main() {
getSum(2, 56, 23, 12, 4, 2)
}
// 可变参数
func getSum(nums ...int) { //意为可变参数其实是一个数组?
sum := 0
for i := 0; i < len(nums); i++ {
sum += nums[i]
}
fmt.Println(sum)
}
- 这里可以看到 可变参数是如何定义的 变量名...数据类型
- 其次通过调用函数,发现可变参数可以一直输入变量,所以可变参数要定义再最后
- 而且同java 可变参数有且只有一个
值传递、引用传递
值传递 对象有基本类型 int string bool float array
/*
值传递 将arr中的值复制一份到arr2上 即开辟了两个空间
所以修改arr2中的元素并不会影响arr
使用值传递的数据有 基础类型,array,struct
*/
func main() {
//值传递
arr := [4]int{1, 2, 3, 4}
update(arr)
fmt.Println(arr)
fmt.Println("========================")
str := "世界"
updateString(str)
fmt.Println(str)
//引用地址传递
}
func update(arr2 [4]int) {
fmt.Println(arr2)
arr2[0] = 100
fmt.Println(arr2)
}
func updateString(str string) {
fmt.Println(str)
str = "你好"
fmt.Println(str)
}
引用类型 对象有 slice map chan...
/*
s1 与s2指向的空间是同一个 s2修改了一个值
s1也会随之变化
*/
func main() {
//切片 其实就是可以扩容的数组
s1 := []int{1, 2, 3, 4}
update2(s1)
fmt.Println(s1)
}
func update2(s2 []int) {
fmt.Println("传递的数据:", s2)
s2[0] = 100
fmt.Println("更新后:", s2)
}
变量作用域
- 在函数中定义的变量叫做局部变量
- 在函数外定义的变量叫做全局变量
// 定义全局变量
var num int = 100
func main() {
temp := 199
if b := 1; b < 10 {
temp := 99
num := 00
fmt.Println(temp) //遵循就近原则 99
fmt.Println(b)
fmt.Println(num) //0
}
fmt.Println(temp) // 199
//fmt.Println(b) b只能在if中使用
fmt.Println(num)
}
func f1() {
num := 11
a := 1
fmt.Println(a)
fmt.Println(num) //11
}
func f2() {
//fmt.Println(a) 不能使用其他函数中定义的变量
fmt.Println(num) //100
}
- 一定要注意变量的作用域
defer 延迟执行
- defer的作用同队列一样 先入后出
- 当然并不意味着defer标识的函数会最后传入参数执行,程序还是顺序传入参数 然后最后执行
func main() {
a := 10
fmt.Println(a) //10
//参数 10传递进去了,不过被延迟到最后执行
defer f(a) // 10
a++
fmt.Println("我在defer后", a) // 11
}
func f(s int) {
fmt.Println(s)
}
函数的理解
函数本身也是数据类型,所以函数也是变量,可以复制
func main() {
fmt.Println(f1) //f1在不加()下使用就是一个变量
fmt.Printf("%T\n", f1) //类型是func(int, int) 定义的函数是什么样的 类型就是什么样的
//定义一个函数类型变量
var f2 func(int, int) = f1
f2(2, 3) //输出 为 2 3 证明 f1 的值赋予了f2
fmt.Printf("%T\n", f2) //func(int, int)
fmt.Println(f2) //地址与f1一致 指向同一个空间 0x69fe60
}
func f1(a, b int) {
fmt.Println(a, b)
}
匿名函数 go是可以函数式编程的
func main() {
ff1() //调用f1函数
ff2 := ff1 //将f1变量的值赋予f2
ff2()
//匿名函数
func() {
fmt.Println("我是匿名函数")
}() //匿名函数自己调用自动
//匿名函数同普通函数一样可以添加参数、返回值
x := func(a, b int) int {
fmt.Println("我是匿名函数", a, b)
return a + b
}(1, 2)
fmt.Println(x)
}
func ff1() {
fmt.Println("f1")
}
回调函数
- 高阶函数 接受一个函数作为参数的函数
- 回调函数 作为一个参数的函数
func main() {
//r := sum(1, 2)
//fmt.Println(r)
r1 := opear(1, 2, sum)
fmt.Println(r1)
r2 := opear(3, 6, mul)
fmt.Println(r2)
r3 := opear(4, 7, func(a int, b int) int {
return a * b
})
fmt.Println(r3)
r4 := opear(8, 4, func(a int, b int) int {
if b == 0 {
return 0
}
return a / b
})
fmt.Println(r4)
}
func sum(a, b int) int {
return a + b
}
func mul(a int, b int) int {
return a - b
}
func opear(a, b int, fun func(int, int) int) int {
r := fun(a, b)
return r
}
闭包
函数调用函数就会生成一个结构:闭包
一个外层函数,内有一个内层函数,内层函数会操作外层函数的局部变量
并且这个外层函数的返回值就是这个内存函数 这就是闭包结构
*一般来说当函数调用完毕 函数中的变量等应该会被销毁,但是闭包结构中的外层函数的局部变量不会随着外层函数的结束而销毁,因为内层函数还在继续使用
func main() {
r1 := inc()
fmt.Println(r1)
v1 := r1() //1
fmt.Println(v1) //1
v2 := r1() //2
fmt.Println(v2) //2
fmt.Println(r1()) //3
fmt.Println(r1()) //4
fmt.Println(r1()) //5
//i重新计数
r2 := inc()
fmt.Println(r2)
v3 := r2() //1
fmt.Println(v3) //1
fmt.Println(r1()) //6
fmt.Println(r2()) //2
}
func inc() func() int { //外层函数
//局部变量
i := 0
//定义一个匿名函数,给变量自增并返回
fun := func() int { //内层函数
i++ //操作外层函数局部变量
return i
}
return fun
}
Go_day02的更多相关文章
随机推荐
- 85、使用Vue.js实现列表选中效果
实际项目中,我们会遇到很多类似的需求,一个列表,需要点击其中一条高亮显示.熟悉JQuery的同学说这个太简单了.可以给这个选中的element设置一个active的class.配合Css样式,让a ...
- NOIP2022 游记
无论结局如何,我都曾经来过. Day -1 zak 模拟赛,被殴打了. Day 0 上午 补模拟赛题. 下午 补模拟赛题. 徐老师过来分配了第二天下午造数据名单. 我造 T2.希望不会太难.(flag ...
- Word08 创新产品展示说明会邀请函office真题
1.课程的讲解之前,先来对题目进行分析,首先需要在考生文件夹下,将Wrod素材.docx文件另存为Word.docx,后续操作均基于此文件,否则不得分. 2.这一步非常的简单,打开下载素材文件,在[文 ...
- VUE学习-编译到浏览器
vue文件时怎样编译运行到浏览器的 http://www.manongjc.com/article/21832.html 通过vue-loader,解析.vue文件,在webpack解析,拆解vue组 ...
- Unity Random
Random 不仅可以随机值,还可以随机其它属性,用了这么久,刚知道... 譬如: rotation 随机Rotation onUnitSphere 球体表面随机点 insideUnitCircl ...
- element ui修改文本框高度以及图标不居中的问题
.el-input__inner{ height:30px !important; .el-input__icon{ line-height: 24px !important; } .el-range ...
- 前端将JSON数据格式化显示
很简单 1 formatJsonData(jsonData) { 2 var smapleDetailData = JSON.stringify(JSON.parse(jsonData), null, ...
- JavaScript 字符串的操作
1. 在指定位置,插入字符串(此需求来源于,img中src没值的字符串标签中,插入图片http地址) // 使用slice写出的 自定义方法,绑定在String的原型链上 String.prototy ...
- numpy.ndarray类型方法
numpy.ndarray 类numpy.ndarray(shape,dtype = float,buffer = None,offset = 0,strides = None,order = Non ...
- tp 获取器的使用中应该怎么append 自定义数据
$data = model('organization_area')->getListByNoPage($where, 'create_time asc');foreach ($data as ...