首页 > 其他分享 >Go语法糖——简短变量声明“:=”

Go语法糖——简短变量声明“:=”

时间:2023-11-28 16:11:23浏览次数:27  
标签:变量 err 作用域 fmt 简短 语法 func Go 声明

参考地鼠文档——GO专家编程中的内容,我总结了关于  := 的几条规则,并以代码举例的运行结果来说明可行性,以避免编程中出现一些陷阱。

  • 规则一:不能用于函数外部

package main
import "fmt"

rule := "Short variable declarations"
func main() {
    fmt.Println(rule)
}
编译错误提示syntax error: non-declaration statement outside function body,表示非声明语句不能出现在函数外部。可以理解成:= 实际上会拆分成两个语句,即声明和赋值。赋值语句不能出现在函数外部的。
  • 规则二:左边必须有新变量,多变量赋值时旧变量可能会重新赋值

func fun() {
    i := 0
    i, j := 1, 2
    fmt.Printf("i = %d, j = %d\n", i, j)
}

  多变量声明时,按照以下规则:

  • :=左侧存在新变量时(如 j ),那么已声明的变量(如 i )则会被重新声明,不会有其他额外副作用。
  • :=左侧没有新变量是不允许的,编译会提示no new variable on left side of :=
>>> i = 1, j = 2
  • 规则三:变量作用域问题

func fun() {
    i, j := 0, 0
    if true {
        j, k := 1, 1
        fmt.Printf("j = %d, k = %d\n", j, k)
    }
    fmt.Printf("i = %d, j = %d\n", i, j)
}

注意 block if 中声明的 j ,与上面的 j 属于不同的作用域,因此两者是两个作用域中同名的不同变量。代码结果如下:

j = 1, k = 1
i = 0, j = 0

当 := 使用过于频繁时,我们需要注意作用域的陷阱,看如下代码:

func Redeclare() {
    field, err:= nextField()   // 1号err
    if field == 1{
        field, err:= nextField()     // 2号err
        newField, err := nextField() //  3号err
        ...
    }
    ...
}

注意上面声明的三个err变量。
2号err与1号err不属于同一个作用域,:=声明了新的变量,所以2号err与1号err属于两个变量。
2号err与3号err属于同一个作用域,:=重新声明了err但没创建新的变量,所以2号err与3号err是同一个变量。

如果误把2号err与1号err混淆,就很容易产生意想不到的错误。

标签:变量,err,作用域,fmt,简短,语法,func,Go,声明
From: https://www.cnblogs.com/shui00cc/p/17862210.html

相关文章

  • Can Pre-Trained Text-to-Image Models Generate Visual Goals for Reinforcement Lea
    概述LearningformtheVoid(LfVoid)根据给定的languageinstruction对observation进行appearance-basedandstructure-based修改得到goalimages,为RL提供奖励信号。提升了example-basedRLmethods,无需rewardfunction或者demonstration就可以解决一些robotcontroltasks问......
  • 秦疆的Java课程笔记:43 流程控制 break、continue、goto
    break:在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break也在switch语句中使用)publicclassBreakDemo{publicstaticvoidmain(String[]args){inti=0;while(i<100){......
  • Elasticsearch query查询语法 es
    Elasticsearch查询语法1.查询基本语法结构GET/{索引名}/_search{ "from":0,//返回搜索结果的开始位置 "size":10,//分页大小,一次返回多少数据 "_source":[...需要返回的字段数组...], "query":{...query子句...}, "aggs":{..aggs子句..},......
  • Golang - context.TODO()和context.Background()的区别
    context.Background():上下文的默认值(创建上下文的默认起点),这个函数返回一个空context,返回值就是根节点,这只能用于最高等级(在main函数、初始化或顶级请求处理中),因为所有其他的上下文都应该从它衍生(Derived)出来context.TODO():通常用作占位符或临时解决方案,只在不确定应该使用哪种上......
  • go程序启动过程
    go的启动入口函数对go有开发经验的朋友都知道,main函数不是真正的启动入口,只是go暴露给用户编写的业务的接口。这点上基本所有的语言都是类似,在main函数调用前,go需要做一系列的准备工作。go的启动在runtime/rtoXXX.s,xxx是因为平台的差异。不同系统不同芯片都有自己的启动......
  • odigos 基于ebpf 以及OpenTelemetry 的分布式tracing 解决方案
    按照odigos官方的介绍是不需要进行代码的修改就可以实现方便的跨应用的分布式trace,目前支持java,python,net,go,js等语言目前看官方的介绍,安装是比较简单的(核心基于了k8s),目前官方文档比较清晰可以试用下说明目前开源分布式trace的工具是越来越多了,同时基于ebpf以及OpenTelemetry标......
  • django 创建model 并迁移生成表 在创建记录的写法流程
    django创建model并迁移生成表在创建记录的写法流程在Django中,创建一个新的模型并迁移生成表的步骤如下:在你的应用的models.py文件中定义模型。例如,我们创建一个名为Person的模型,它有name和age两个字段:fromdjango.dbimportmodelsclassPerson(models.Model):name=m......
  • django-单表操作
    一、常用字段和非常用字段#常用字段-IntegerField整数-AutoField自增字段-BooleanFieldbool类型-CharField字符串类型-DateField日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。-DateTimeField日期时间字段,格......
  • Django - 多条queryset合并,并排序
     fromitertoolsimportchainfromoperatorimportattrgetter#拿到多条querysetqueryset1=model.objects.filter(status=1).all()queryset2=model.objects.filter(status=2).all()#将上面两组查询结果合并,并设置排序方式:-create_timenew_queryset=sorted......
  • What's new in dubbo-go-pixiu v1.0.0
    dubbo原生网关dubbo-go-pixiuv1.0https://github.com/apache/dubbo-go-pixiu/releases/tag/v1.0.0-rc2正式发版了,项目从2019年一路走来,四年磨剑,感谢从铁城、张天到吕梦超三位负责人。目前,dubbo-go-pixiu可作为dubbo/dubbogo服务网关,也可作为dubbo/dubbogo服务的s......