在《基础篇》和《入门篇》当中,我们已经知道了Golang的基本属性、方法等知识,接下来,在本文当中就详细介绍一下Go中的一些常用操作和语法函数,包含下面几个内容。相信阅读完后续章节的朋友,就能大致对Go语言的项目开发有了一个基础的掌握。
为响应交流的朋友反馈篇幅过长的问题,本主尽量分开不同的知识点(PS:勤快点,别懒了),细致短促的讲解Go当中的知识点,以便朋友更加深入的学习。
- 分支、循环
- 函数
- 指针
- 结构体
1、分支、循环
(1) if 语句
语法格式如下:(与java类似,区别在于它的条件不需要括号"()")
if expression(表达式) { /* 为 true 时执行 */ } else if expression2 { /* 为 false ,expression2为true时执行 */ } else{ /* 都为false时,执行*/ }
示例:
func main() { /* 定义局部变量 */ var a int = 2 /* 使用 if 语句判断布尔表达式 */ if a < 5 { /* 如果条件为 true 则执行以下语句 */ fmt.Printf("a 小于 5\n" ) } fmt.Printf("a 的值为 : %d\n", a) }
(2)switch 语句
语法格式如下:(与java类似,区别在于Go中不需要像java一样在每一个case当中显式声明break,当找到匹配项时自动跳出)
switch var1 { // var1可以是任意类型 case val1: // 可以是同类型的任意值 ... case val2: // 且必须是相同的类型 ... default: ... }
示例:
package main import "fmt" func main() { /* 定义局部变量 */ var name string = "bboyHan" var salary int = 30 //方式一: switch age { case 30000: name = "Tom" case 25000: name = "Jerry" case 22000,25000,30 : name = "bboyHan" //case 后可以由多个数值 default: name = "unknown" } //方式二: switch { case name == "Tom" : fmt.Printf("good man!\n" ) case name == "Jerry", name == "bboyHan" : fmt.Printf("lazy man\n" ) case name == "Kimi" : fmt.Printf("good woman\n" ) case name == "Tomy": fmt.Printf("a dog\n" ) default: fmt.Printf("unknown\n" ); } fmt.Printf("He(She) is a %s \n", name );
注意点:case定义的常量不可以重复,case后可以有多个常量值。另外,case中的表达式是可选的,可以省略。如果该表达式被省略,则被认为是switch true,并且每个case表达式都被计算为true,并执行相应的代码块。
func main() { num := 75 switch { case num >= 0 && num <= 50: fmt.Println("num is greater than 0 and less than 50") case num >= 51 && num <= 100: fmt.Println("num is greater than 51 and less than 100") case num >= 101: fmt.Println("num is greater than 100") } }
(3)select 语句
select会随机执行一个可运行的case。如果没有case可运行,它将会阻塞,直到有case可运行。通常可以使用在通信之上,比如接收和发送消息,生产者与消费者的关系等等。如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。记住!其它的是不会执行。
package main import "fmt" func main() { var c1, c2, c3 chan int //定义通信通道 var i1, i2 int select { case i1 = <-c1: fmt.Printf("接收消息:received ", i1, " from c1\n") case c2 <- i2: fmt.Printf("发送消息:sent ", i2, " to c2\n") case i3, ok := <-c3: if ok { fmt.Printf("接收消息:received ", i3, " from c3\n") } else { fmt.Printf("c3 is closed - 消息关闭\n") } default: fmt.Printf("no communication - 未连接 \n") } }
2、循环语句
Golang当中,for是唯一的循环语句,并不像java一样还有while、dowhile等语法,显得更加简单明了。
语法结构:
for init; condition; post { //执行内容 } // init : 初始化语句,只执行一次 // condition : 判断条件 // post : 迭代后执行的语句 // init、condition、post 三部分都可以省略,可以选择,如: for condition { } for { }
示例:
package main import "fmt" func main() { nums := []int{1, 2, 3} sum := 0 for _, num := range nums { // 埋雷, orz,想知道"_"时什么意思请往下看 sum += num } fmt.Println(sum) for i, num := range nums { if num == 2 { fmt.Println(i) } } kvs:= map[string]string{"a":"apple","b":"banana"} for k,v := range kvs{ fmt.Printf("%s - %s\n",k,v) } for i,c := range "go"{ fmt.Println(i,c) // 打印字符ASCII值 } }
其中还有break、continue跳出循环语句的使用,与其它语言类似
//continue func main() { for i := 1; i <= 10; i++ { if i%2 == 0 { continue //跳出本次循环 } fmt.Printf("%d ", i) } } //break func main() { for i := 1; i <= 10; i++ { if i > 5 { break //当大于5时,结束循环 } fmt.Printf("%d ", i) } fmt.Printf("\nline after for loop") }
func main() { var a int A: for a < 5 { if a == 3 { a++ goto A //当执行到这时,返回到第3行继续执行代码 } fmt.Printf("%d, --- \n", a) a++ } }
2、函数
我在《入门篇》提到过一个Go语言当中必不可少的函数,就是main函数,所谓函数,就是执行特定任务的代码块,在Go中,函数定义比较有趣的一点就是,它可以有多个返回值,十分方便
(1)语法格式:
func funcName(param1 type1, param2 type2) (output1 type1, output2 type2) { //... //函数具体实现内容 //返回多个值 return value1, value2 }
示例:(定义两个数交换的函数)
func swap(i int, i2 int) (int, int) { return i2,i } //输入3、5,得出结果5,3 func main() { a,b := swap(3,5) fmt.Println(a,b) }
扫雷:上文当中出现了Go当中一个有趣的标识符,就是空白标识符"_",它的作用是可以代替任何类型的任何值。同时,它的作用还可以被当作一个占位符表示,在后续的函数方法当中不使用其值的情况下,就可以使用"_"来代替。
就像在上面的例子当中求数组[1,2,3]的和时,不需要使用索引的值,就使用了空白标识符
(3)可变参数
另外,Go同样支持可变参数的传递
示例:(定义一个函数,遍历并输出)
func numFunc(arg ...int) { for _, n := range arg { fmt.Printf("The number is: %d\n", n) } }
(2) 函数可作为变量
在Go中,函数也是一种变量,我们可以通过type来定义它,在下文介绍的结构体中实例具体阐述。
type count int func NewCount(i int) count { return count(i) } func main() { c := NewCount(10) fmt.Println(c) }
3、指针
在函数当中,我们也听说过值传递和引用传递,在Go中,引入了一个指针的概念。所谓指针,就是指变量在内存当中,是存放于一个地址上的,修改变量实际是修改变量地址处的内存。
传递指针,其实就是引用的传递,那就让我们来看看如何定义指针的吧
语法格式:
var a *int // 使用"*",定义指针类型 var b = &a // 使用"&",接收a的地址
示例:
func main() { var i int var ptr *int var pptr **int i = 10 ptr = &i //接收i的地址值 pptr = &ptr //接收ptr的地址值 fmt.Printf("%d\n", i) fmt.Printf("%d\n", *ptr) fmt.Printf("%d\n", **pptr) }
4、结构体
(1)接口
接口,即一组方法签名,当类型为接口中定义的方法进行实现时,就可以称之为实现了一个接口。在java当中我们也有面向对象的概念,这与OOP的概念十分相似,接口指定了类型应该具有的方法,类型决定了如何实现这些方法。
语法结构:
// 定义接口 type interface_name interface { method1 [return_type] method2 [return_type] method3 [return_type] ... methodN [return_type] } // 定义结构体 type struct_name struct { ... } // 实现接口方法 func (struct_name_variable struct_name) method_name1() [return_type] { // 方法实现 ... } func (struct_name_variable struct_name) method_namen() [return_type] { // 方法实现 ... }
示例:
package main import "fmt" type dosomething interface { work() int study() int } type Student struct { name string age int } func (stu Student) work() int { fmt.Printf("name:%s,age:%d -- work\n", stu.name, stu.age) return 3 } func (stu Student) study() { fmt.Printf("name:%s,age:%d -- study\n", stu.name, stu.age) } func main() { s1 := new(Student) s1.name = "zhang san" s1.age = 23 s2 := new(Student) s2.name = "Li si" s2.age = 23 i := s1.work // 作为变量使用 a := i() fmt.Println(a) s2.study() }
我们知道,在java当中,有一个类叫做Object,且认为所有的类都继承实现了Object类,作为java当中的顶级存在。在Go中,虽然没有继承这一概念,但同样的,也认为任意的类型都实现了空interface(我们这样定义:interface{}),也就是包含0个method的interface。
注意点:
1、接口对象不能调用实现对象的属性
2、interface可以被任意的对象实现
3、一个对象可以实现任意多个interface
4、interface的变量可以持有任意实现该interface类型的对象
----------------------------------------------------------------------
后续章节,敬请期待......
有任何建议或问题,欢迎加微信一起学习交流,欢迎从事IT,热爱IT,喜欢深挖源代码的行业大牛加入,一起探讨。
个人微信号:bboyHan