写了快一个月的Go,已经没有什么陌生感了。bash
一行代码写完,不会在行尾本能的敲上“;”,直接Enter键换行;架构
定义变量把变量名放在前面,类型放在后面;框架
使用struct去定义本身想要的数据模型就比如定义一个Java中的model同样……函数
这些不用能够通过大脑加工思考,就想本身还在写Java同样。微服务
还记得当时在看《Go实战》的时候看到变量类型后置的声明方式,我还在极力吐槽这种不人性的语法,若是我已经站在了真香的队伍里,和其余的真香同窗别无二致。工具
感慨,人的适应能力真的强👍ui
做为一个Java重度爱好者,其实在每次写Go的时候都会不由自主的把二者进行对比,在写文章的时候也会常常提到。固然了,今天主要说的仍是Go的函数。spa
func f(a int, b int) (ret int, err error) {
fmt.Println("This is function")
return
}
复制代码
没错,这大概就是一个典型的Go风格的函数,那么它有哪些特点code
入参的变量也是变量后置的,这里a变量和b变量是相同类型的,因此也能够写成cdn
a, b int
复制代码
对于不一样类型的参数须要分开定义。
除此之外,入参还支持不定参数
好比能够这样定义
func f(args ...int) {
for _, arg := range args {
fmt.Println(arg)
}
}
复制代码
针对不定参数的函数,咱们能够这样调用
f(1)
f(1, 2)
f(1, 2, 3)
避免了咱们在函数里定义一长串变量的状况。
上面的不定参数是int类型的,那么是否支持多种类型混用的不定参数呢?
是能够的,使用...interface{}这种形式
func f(args ...interface{}) {
for _, arg := range args {
switch arg.(type) {
case int:
fmt.Println("It is int type")
case string:
fmt.Println("It is string type")
case int64:
fmt.Println("It is int64 type")
}
}
}
复制代码
注意,这里的i.(T)形式不是强制转换或者隐式类型转换,这是类型断言,表示断定类型的。
Go里面是没有隐式类型转换的,不只没有,并且强制类型转换也很严格。
不一样于Java,Go函数是能够支持多返回值的,好比这里返回了ret和err两个参数。
返回值的定义方式也很灵活,能够写成
func f(a int, b int) (int, error) {
fmt.Println("This is function")
return
}
复制代码
若是返回只有一个参数能够写成
func f(a int, b int) (ret int) {
fmt.Println("This is function")
return
}
复制代码
或者
func f(a int, b int) int {
fmt.Println("This is function")
return
}
复制代码
在前面的文章,咱们也顺带提过,对于函数返回的值,有些咱们不关心或者不须要的话,咱们不能抹掉他的位置,可是可使用"_"来表示这个参数的存在,只是不用而已,好比这样调用上面的函数是不行的
ret := f(1, 2) // 缺乏err返回值
复制代码
可是这样是OK的
ret, _ := f(1, 2)
复制代码
或者这样
_, err := f(1, 2)
复制代码
error接口是Go标准库为了错误处理提供的接口。
通常在业务代码中,咱们会调用某个方法后,断定方法对应的值是否为nil断定方法是否被正常执行
if err != nil {
// 没有正常执行
} else {
// 正常执行
}
复制代码
说到error,正好说说panic()和recover()两个函数
当咱们遇到一些err的时候,咱们可能就会直接抛出panic,这里的panic能够近似理解为Java里面的Exception,即抛出异常。
if err != nil {
panic(err)
}
复制代码
一旦抛出panic,则程序将会终止,除非遇到一种状况,即有recover的存在。
说到recover则不得不提defer
defer是Go里面的新特性,有点类型Java里面的finally,承担回收资源或者解锁这类的收尾工做,可是比finally要灵活,Go函数的defer能够放在函数的任意位置,无论函数是否正常执行,在跳出函数前都会执行defer定义的函数。
接着说recover,若是在函数抛出panic,只要在最后遇到recover也是能够恢复正常的,形式以下
defer func() {
if ret := recover(); ret != nil {
fmt.Println("Catch Runtime Error:)
}
}
复制代码
每一个函数都以func开始,来代表本身是一个函数。
那么学过Java的确定会问,没有像public、private这样的访问修饰符吗?
没有,可是Go经过另一种规则实现了访问范围便可见性。对于函数名使用大写字母开头,则表示能够被其余包使用,若是使用小写字母开头,则只能本包内使用。
固然,这个规则,也适用于变量的声明。
和Java等其余语言同样,Go函数也有匿名函数。
func (a, b int, s string) int {
...
}
复制代码
能够经过直接在后面赋值的方式直接执行
func (a, b int, s string) int {
...
}(1, 2, "test")
复制代码
这里主要从Go语言的函数构成包括关键字func,入参和返回值介绍Go函数的一些特性。固然了,Go函数还有不少灵活性就再也不一一阐述了,有待你我在业务项目中慢慢实践体会了。
今天去参加了一个技术沙龙,主题是数据存储与微服务架构实践方面的。
这是本身第一次除了参加公司组织的各类会议之外,本身主动报名的线下技术沙龙。
会上听到了阿里、百度的大佬分享关于过去的技术沉淀和对将来技术方向的展望,总体仍是蛮有收获的。
拓宽了本身的知识面,也加深了对一些框架或者工具的理解,好比ServiceMesh。以前对于ServiceMesh的理解仅限于阅读各类文章,本身的理解也比较有限,此次经过阿里大佬的解释,更加清晰的了解了ServiceMesh以及它的优点。
最后晒一下在回答问题环节,主办方送的马克杯,好评
我的公众号:JackieZheng 我会将我最新的文章推送给您,并和您一块儿分享我平常阅读过的优质文章