首页 快讯正文

上饶二手房网:Go语言入门教程系列——函数、循环与分支

admin 快讯 2020-05-10 7 0

本文始发于小我私家民众号:TechFlow,原创不易,求个关注


今天是Golang专题的第四篇,这一篇文章将会先容golang当中的函数、循环以及选择判断的详细用法。

函数

在之前的文章当中实在我们已经接触过函数了,由于我们写的main函数本质上也是一个函数。只不外由于main函数没有返回值,也没有传参,以是省略了许多信息。

func main() {
 fmt.Println("Hello World")
}

下面,我们来看看一个完整的函数是怎样的,这是golang官网上的例子。

func add(x int, y int) int {
    return x + y
}

这是一个异常简朴的a+b的函数,我想人人应该都能看懂。我们来重点关注一下函数的花样。首先是func关键字,我们使用这个关键字界说一个函数,之后随着的是函数名,然后是函数的传参,最后是函数的返回值。

这个顺序可能和我们之前普遍接触的语法不太一样,例如C++当中是把函数返回类型写在最前面,然后是函数名和传参。再好比Python当中则是没有返回值的任何信息,只有def关键字和函数名以及传入的参数。

golang有些像是Python和C++的综合体,总体来说我以为内在上更靠近C++,然则写法上和Python更靠近一些。

我们理解了函数的界说之后,下面来看看golang当中支持的一些特征。

变量简写

在变量声明的时刻,我们若是界说两个相同类型的变量是可以把它们举行缩写的。好比我们界说两个int类型的变量,划分叫做a和b。那么可以简写成这样:

var a, b int

同样,在函数当中,若是传入的参数类型相同,也一样是可以简写的。我们可以把x和y两个参数缩写在一起,用逗号离开,共享变量类型。

func add(x, y int) int {
    return x + y
}

多值返回

在前面先容golang特征的时刻曾经提到过,golang作为一个看起来很守旧的语言,然则却支持许多新鲜的特征。其中最着名的一个特征就是函数支持多值返回,纵然是现在,也只有少量的语言支持这一特征。

在许多语言当中,若是需要返回多个值,往往需要用一个结构体或者是tuple、list等数据结构将它们包装起来。然则在golang当中支持同时返回多个效果,这将会极大地利便我们的编码。

func sample() (string, string) {
    return "sample1", "sample2"
}

多值返回也会有一个小小的问题,就是若是我们要返回的值过多,会导致这个return会写得很长,或者是组装的逻辑变得很庞大。或者是很容易发生遗漏、搞混顺序之类的问题,golang当中针对这个问题也举行优化,支持我们对返回值举行命名。当命名的变量赋值完成之后,我们就可以直接用return关键字返回所有数据。

这个操作很难用语言形貌很清晰,我们来看下面的例子:

func sample(x, y, z int) (xPrime, yPrime, zPrime int) {
    xPrime, yPrime, zPrime = x-1, y+1, z-2
    return 
}

在上面的代码当中,在返回之前,我们先给要返回的值起好了名字,我们在函数体当中对这些值举行赋值完成之后,我们就可以直接return了,golang会自动将它们的值填充举行返回。这样不只可以简化一定的编码历程,也可以增添可读性。

defer

golang的函数当中有一个特殊的用法,就是defer。这个用法听说其他语言也有,然则我暂时没有见到过。defer是一个关键字,用它修饰的语句会被存入栈中,直到函数退出的时刻执行

好比:

func main() {
 defer fmt.Println("world")

 fmt.Println("hello")
}

上面这两行代码虽然defer的那一行在先,然则并不会被先执行,而是等main函数执行退出之前才会执行。

看起来这个用法有一点点怪,然则它的用处很大,经常用到。好比当我们打开一个文件的时刻,不管文件有没有打开乐成,我们都需要记得关闭文件。但若是文件打开不乐成可能就会有异常或者是报错,若是我们把这些情形所有都考虑到,会变得异常庞大。以是这个时刻我们通常都会用defer来执行文件的关闭。

要注重的是,defer修饰的代码会被放入栈中。以是最后会凭据先进后出的原则举行执行。好比:

func main() {
 for i := 0; i < 10; i++ {
  defer fmt.Println(i)
 }

 fmt.Println("done")
}

最后执行的效果是9876543210,而不是相反。这一点蛮主要的,有的时刻若是搞混了,很容易出现问题。

循环

和其他语言差别,Golang当中只有一种循环,就是for循环。没有while,更没有do while循环。在golang的设计中设想当中,只需要一种循环,就可以实现所有的功效。从某种程度上来说,也简直云云,golang中的循环有点像是C++和Python循环的结合体,聚集两种所长。

首先,我们先来看下for循环的语法,在for循环当中,我们使用分号离开循环条件。循环条件分为三个部门,第一个部门是初始化部门,我们对循环体举行初始化,第二个部门是判断部门,判断循环竣事的终止条件,第三个部门是循环变量的改变部门。

写出来大概是这样的:

for i := 0; i < 10; i++ {
    fmt.Println(i)
}

这个语法是不是和C++中的循环很像呢?可以说除了没有括号之外,基本上就是一样的。golang当中同样支持++的自增操作,不外golang中只支持i++,而不支持++i。

和C++一样,这三段当中的任何一段都是可以省略的,好比我们可以省略判断条件:

for i := 0; ; i++ {
    fmt.Println(i)
    if i > 10 {
        break
    }
}

我们也可以省略循环变量的自增条件:

for i := 0; i < 10; {
    i += 2
    fmt.Println(i)
}

甚至可以所有省略,若是所有省略的话,等价于C++中的while(true)循环,也就是死循环。

range的用法

若是我们用循环遍历一个数组或者是map,它的这个用法和Python中的用法异常类似。我们来看下,如果我们有一个数组是:

nums := []int{2, 3, 4}
sum := 0
for i, v := range nums {
    sum += v
    fmt.Println(i)
}

这个用法等价于Python中的for i, v in enumerate(nums)。也就是通过range会同时返回数组和map中的下标与对应的值,我们再来看下map,实在也是一样的。

kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
    fmt.Printf("%s -> %s\n", k, v)
}

若是你看不懂map和数组的界说没有关系,我们会在之后的文章当中再来详细解说,这篇的主要内容是循环。我们只需要看得懂for循环的range操作即可。

判断

golang当中支持if与switch举行条件判断。我们先来看if,在golang当中的if和Python对照靠近,在if的判断条件外面不需要加上小括号(),然则if的执行条件当中必须要大括号{},纵然只有一行代码。

好比适才我们写的循环中的谁人break。

for i := 0; ; i++ {
    fmt.Println(i)
    if i > 10 {
        break
    }
}

在判断中初始化

上面的逻辑在各个语言中都大同小异,许多语言都是这么写的。然则golang对于if另有特殊的支持,golang支持在if条件当中加上初始化信息。

好比:

if v := sample(); v < 10 {
    fmt.Println(v)
}

上面当中的v是在if执行的时刻才举行的初始化,也就是说我们将变量的初始化和if判断结合在了一起。这个用法异常主要,在golang当中也大规模使用,以是我们一定要学会这个用法。

switch

golang当中也支持switch用法,它的基本套路和C++一样,然则在细微的地方又做了优化。

好比和if一样,switch也支持在执行的时刻初始化。好比:

switch flag := sample(); flag {
case "a":
    fmt.Println(flag)
case "b":
    fmt.Println(flag)
default:
    fmt.Println(flag)
}

看明了了吗,代码当中的flag是我们执行switch的时刻才建立出来的。分号之前的都是初始化的代码,分号之后的表达式才是switch举行判断的内容。

另有一个小细节需要注重,在golang当中使用switch的时刻,每个case的判断条件后面不需要再加上break。我们在写其他语言的时刻,若是用到switch要么就是忘记了case的执行条件后面要加上break,要么就是写许多break异常贫苦。golang的设计者以为每个case都加上break太二了,由于人人基本上都只用switch执行一个case,以是就去掉了必须要加上break这个设定。

switch执行顺序

在golang当中,switch的判断条件凭据顺序执行。

为什么要强调这个呢?由于你很有可能会看到有些人的代码里的switch没有判断条件,好比:


switch a := sample();{
case a < 5:
    fmt.Println(a)
case a > 5:
    fmt.Println(a)
default:
    fmt.Println("end")
}

在上面这段代码当中,我们基本没有为switch设置判断的凭据,这段逻辑完全等同于若干个if-else条件的枚举,它在golang当中同样是允许的。

题外话

今天本来是分布式专题,但实在是没有想到什么很好的问题,我也不喜欢强求,爽性就换个主题吧。以后分布式专题还会更新,不外可能要改成间歇式的了,后面想少写点理论,能够分享一点可以现实用上的器械(以是需要的时间对照久)。

不知道人人从今天的内容当中有没有感受到golang这门语言的个性,许多地方看起来中规中矩,却又能缔造出新的用法来,至少我是很信服设计者的想法的。golang当中这些新特征初见的时刻往往会以为不喜欢和排挤,怎么看怎么怪异,然则写多了之后照样蛮香的。

今天的文章就到这里,扫码关注,获取更多优质文章。

列位看官大大,犒赏个关注再走吧~

,

皇冠会员APP

皇冠体育APP是一个开放皇冠代理APP下载、皇冠会员APP下载、皇冠线路APP下载、皇冠登录APP下载的平台,皇冠体育APP上最新登录线路、新2皇冠网址更新最快,皇冠体育APP开放皇冠会员注册、皇冠代理开户等业务。

版权声明

本文仅代表作者观点,
不代表本站诚信在线的立场。
本文系作者授权发表,未经许可,不得转载。