Go语言的学习之旅【三】
一、常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | const a int = 123 //常量定义const,显式 //a = 456 //修改常量值,会报错 Cannot assign to a,无法赋值 const b = 23 //隐式 const c,d = 1, "s" //多重赋值 const e,f int = 6,7 //多重赋值,同类型 const ( //常量枚举 g = 1 h = "asb" i = len(h) ) fmt.Println(a,b,c,d,e,f,g,h,i) //iota 特殊常量,在定义是为0,后面每行都会计数+1 const ( j = iota k = iota //同一个const中,iota会计数 l //即使不继续赋值也会计数 m = "abc" //即使定义其他数,iota还是会计数 n //这时候n都值为上一个m都值,不过iota还是计数 o = iota //此时不受m影响,iota继续计数 ) const p = iota //这时候iota会刷新计数 fmt.Println(j,k,l,m,n,o,p) const ( q = 1<<iota //1左移0 r = 3<<iota //3左移1 s //这个时候s都值为,3 << 2 t //t为 3 << 3 ) //可以认为s不仅仅只是取上一个r的结果,而是r的内容,t同理 fmt.Println(q,r,s,t) |
二、运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | //算术运算符 var a = 1+1 b := 2-1 c := 10*9 d := 10/3 //默认int整型类型,答案是3 e := 8%2 //取模(求余) a++ //自增 b-- //自减 //++a,--a这样的写法不允许 //f := a++ 这样的组合也不被允许 fmt.Println(a,b,c,d,e) //关系运算符 var g int = 1 var h int = 2 if g == h{ //if(g==h)带括号也是可以的 fmt.Println( "相等" ) } else { fmt.Println( "不相等" ) } if (g < h){ fmt.Println( "g小于h" ) } else { fmt.Println( "g大于h" ) } if (g <= h){ fmt.Println( "g小于等于h" ) } else { fmt.Println( "g不小于等于h(g大于h)" ) } //逻辑运算符 var i bool = true var j bool = false if (i && j){ //i且j都为真 fmt.Println( "i,j都为true" ) } else { fmt.Println( "i,j存在一个为false,或者都为false" ) } if (i || j){ //i或j为真 fmt.Println( "i为true,或者j为true" ) } else { fmt.Println( "i跟j都为false" ) } if (!(i && j)){ fmt.Println( "(i && j)为false,在取反为true" ) } else { fmt.Println( "(i && j)为true,在取反为false" ) } //位运算符 /* k=60, 二进制 0011 1100 l=13 0000 1101 */ var k,l = 60, 13 m := k & l //且 1=1&1,m二进制 0000 1100 n := k | l //或 1=1|0, n二进制 0011 1101 o := k ^ l //异或 1 = 1^0, o二进制 0011 0001 p := k << 1 //左移 0011 1100 向左移动1位,p二进制0111 1000 q := k >> 1 //右移 0011 1100 向左移动1位,p二进制0001 1110 fmt.Println(m,n,o,p,q) //赋值运算符 var r int r = k //简单都赋值 fmt.Println(r,k,r) r += k //等于r = r + k fmt.Println(r,k,r) r -= k //同上 fmt.Println(r,k,r) r *= k //同上 fmt.Println(r,k,r) r /= k //同上 fmt.Println(r,k,r) r %= k //同上 fmt.Println(r,k,r) r <<=k //同上 fmt.Println(r,k,r) r >>=k //同上 fmt.Println(r,k,r) r &= k //同上 fmt.Println(r,k,r) r |= k //同上 fmt.Println(r,k,r) r ^=k //同上 fmt.Println(r,k,r) //其他运算符 var s *int fmt.Println(&r) //表示取到r的内存地址 r = 10 s = &r fmt.Println(*s) //这个是一个指针 fmt.Println(s) //指针地址 //运算符优先级 /*由上至下 (优先级递减),同级由左到右(优先级递减), 符号 * / % << >> & &^ 符号 + - | ^ 符号 == != < <= > >= 符号 && 符号 || */ |
三、条件与循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | func main() { //if...else...语句 var a int = 1 if a == 1 { fmt.Println( "a等于1" ) if a > 0 { //嵌套if语句 fmt.Println( "a大于0" ) } } else { fmt.Println( "a不等于1" ) } //switch语句 switch a { case 1: fmt.Println( "a等于1" ) case 2: fmt.Println( "a等于2" ) default : fmt.Println( "上面条件都不符合" ) } //select语句 //select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。 //select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。 var i, j, k, ch, stopCh chan int //定义通信int类型 var o, p int select { case o = <-i: fmt.Println( "received" , o, "from i" ) case j <- p: //阻塞 fmt.Println( "sent " , p, " to j" ) case q, ok := (<-k): //这里是q := <-k, ok是接收状态(非阻塞)会造成cpu使用高 if ok { fmt.Println( "received" , q, " from k" ) } else { fmt.Println( "k is closed" ) } default : fmt.Println( " no communication" ) } //构建通道 ch = make( chan int) stopCh = make( chan int) //并发匿名函数 go func () { // 从3循环到0 for v := 3; v >= 0; v-- { // 发送3到0之间的数值 ch <- v // 每次发送完时等待 time.Sleep(time.Second) } stopCh <- 1 }() fmt.Println( "-------------" ) // 遍历接收通道数据 for { select { case x := <- ch: fmt.Println( "received x " , x) case y := <- ch: fmt.Println( "received y " , y) case _ = <- stopCh: goto end //跳转操作 } } end: } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //循环体 for i := 0; i < 100; i++{ if (i == 0){ continue //跳过此次循环 } if (i == 66){ break //跳出循环 } fmt.Println( "i:" ,i) } for i := 0; i < 100; i++{ if (i == 55){ goto end //跳到end处 } fmt.Println( "ii:" ,i) } end: fmt.Println( "结尾end" ) var j int = 100 for { //死循环,也可以 for true{} j-- if (j == 0){ break } fmt.Println( "j:" ,j) } fmt.Println( "退出" ) |
四、函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package main import "fmt" //全局变量 var g int = 10 //声明一个函数类型 type cb func (int) int func main() { fmt.Println( "Hello, World!" ) var x,y int = 1,2 g = x + y fmt.Println( "g:" ,g)<br> //重新定义g<br> var g int = 20<br> //这里会优先使用局部参数g<br> fmt.Println("局部g:",g);<br> a, b := swap(1, 2) fmt.Println(a, b) var c, d = 4, 5 swap2(&c, &d) fmt.Println(c, d) r := test(10, func (i int) int { //直接传入匿名函数 return i }) fmt.Println(r) t := test(100, callback) fmt.Println(t) } //函数作为参数传递 func test(x int, f cb) int { return f(x) } func callback(x int) int { fmt.Println( "自定义回调函数" ,g) return x } //交换值,引用传递 func swap2(x *int, y *int) { var temp int temp = *x *x = *y *y = temp } //交换值 func swap(x int, y int) (int, int) { var temp int temp = x x = y y = temp return x, y } |
五、总结
go语言中常量设定是不可修改,运算符类型跟其他语言相差无几,主要自增、自减没有++i,--i,a=i++这样的操作。条件跟循环大部分语言一致,条件语句还新增select语句(咋一看还以为是sql语法),其实是专门给信号判断的一个语句。还保留了goto end跳转语法。函数方法很喜欢,虽然跟c挺像的。整体还是很好接受,有一点其他语言基础的(特别是c语言),还是很快上手!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!