【学习笔记】go语言中变量赋值规则


前言

本文章是go语言的学习笔记,用作go的入门学习,已经能熟虑使用go的就不用看了。


1.标准格式

var 变量名 类型 = 表达式
例如:游戏中,玩家的血量初始值为100。可以这样写:
var hp int = 100
这句代码中,hp为变量名,类型为int,hp的初始值为100。 上面代码中,100和int同为int类型,int可以认为是冗余信息,因此可以进一步简化初始化的写法。

2.编译器推导类型的格式

在标准格式的基础上,将int省略后,编译器会尝试根据等号右边的表达式推导hp变量的类型。
var hp = 100
等号右边的部分在编译原理里被称做“右值”。 下面是编译器根据右值推导变量类型完成初始化的例子。

      var attack = 40
        
       var defence = 20
       
       var damageRate float32 = 0.17
        
        var damage = float32(attack-defence) * damageRate
       
      fmt.Println(damage)

代码说明如下:
·第1和3行,右值为整型,attack和defence变量的类型为int。 ·第5行,表达式的右值中使用了0.17。
Go语言和C语言一样,编译器会尽量提高精确度,以避免计算中的精度损失。 默认情况下,如果不指定damageRate变量的类型,Go语言编译器会将damageRate类型推导为float64。由于这个例子中不需要float64的精度,所以强制指定类型为float32。
·第7行,将attack和defence相减后的数值结果依然为整型,使用float32()将结果转换为float32类型,再与float32类型的damageRate相乘后,damage类型也是float32类型。 ·第9行,输出damage的值。
提示:damage变量的右值是一个复杂的表达式,整个过程既有attack和defence的运算还有强制类型转换。

代码输出如下: 3.4

3.推导声明写法

var的变量声明还有一种更为精简的写法,
例如: hp := 100
这是Go语言的推导声明写法,编译器会自动根据右值类型推断出左值的对应类型。 注意:由于使用了“:=”,而不是赋值的“=”,因此推导声明写法的左值变量必须是没有定义过的变量。若定义过,将会发生编译错误。 如果hp已经被声明过,但依然使用“:=”时编译器会报错,代码如下:

  // 声明hp变量
var hp int
// 再次声明并赋值
hp := 10

编译报错如下: no new variables on left side of :=
提示,在“:=”的左边没有新变量出现,意思就是“:=”的左边变量已经被声明了。 短变量声明的形式在开发中的例子较多,比如:
conn, err := net.Dial(“tcp”,“127.0.0.1:8080”)
net.Dial提供按指定协议和地址发起网络连接,这个函数有两个返回值,一个是连接对象,一个是err对象。如果是标准格式将会变成:
var conn net.Conn
var err error
conn, err = net.Dial(“tcp”, “127.0.0.1:8080”)
因此,短变量声明并初始化的格式在开发中使用比较普遍。 注意:在多个短变量声明和赋值中,至少有一个新声明的变量出现在左值中,即便其他变量名可能是重复声明的,编译器也不会报错,代码如下:
conn, err := net.Dial(“tcp”, “127.0.0.1:8080”)
conn2, err := net.Dial(“tcp”, “127.0.0.1:8080”)
上面的代码片段,编译器不会报err重复定义。

多个变量同时赋值

编程最简单的算法之一,莫过于变量交换。交换变量的常见算法需要一个中间变量进行变量的临时保存。用传统方法编写变量交换代码如下:

 var a int = 100
var b int = 200
var t int

t = a
a = b
b = t

fmt.Println(a, b)

在计算机刚发明时,内存非常“精贵”。这种变量交换往往是非常奢侈的。于是计算机“大牛”发明了一些算法来避免使用中间变量:

  var a int = 100
var b int = 200

a = a ^ b
b = b ^ a
a = a ^ b
fmt.Println(a, b)

这样的算法很多,但是都有一定的数值范围和类型要求。 到了Go语言时,内存不再是紧缺资源,而且写法可以更简单。使用Go的“多重赋值”特性,可以轻松完成变量交换的任务:

  var a int = 100
var b int = 200

b, a = a, b

fmt.Println(a, b)

多重赋值时,变量的左值和右值按从左到右的顺序赋值。 多重赋值在Go语言的错误处理和函数返回值中会大量地使用。例如,使用Go语言进行排序时就需要使用交换,代码如下:

       type IntSlice []int
       
        func (p IntSlice) Len() int          
 { return len(p) }
       func (p IntSlice) Less(i, j int) bool
 { return p[i] < p[j] }
      func (p IntSlice) Swap(i, j int)    
  { p[i], p[j] = p[j], p[i] }

代码说明如下:
·第1行,将[]int声明为IntSlice类型。
·第3行,为这个类型编写一个Len方法,提供切片的长度。
·第4行,根据提供的i、j元素索引,获取元素后进行比较,返回比较结果。
·第5行,根据提供的i、j元素索引,交换两个元素的值。

匿名变量——没有名字的变量

在使用多重赋值时,如果不需要在左值中接收变量,可以使用匿名变量。 匿名变量的表现是一个“_”下画线,使用匿名变量时,只需要在变量声明的地方使用下画线替换即可。
 例如:

  01        func GetData() (int, int) {
02                return 100, 200
03        }
04        
05        a, _ := GetData()
06        
07        _, b := GetData()
08        
09        fmt.Println(a, b)

代码输出如下: 100 200
GetData()是一个函数,拥有两个整型返回值。每次调用将会返回100和200两个数值。

节选自《go语言入门到进阶实战》

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值