Variable

变量与常量

本节目标:

  • 了解 Go 中基础数据类型
  • 变量定义的两种方式以及使用
  • 常量的定义方式以及常见应用场景

数据类型

从计算机底层而言,所有数据都是由比特(Bit:二进制数「位」的缩写 )组成,为了能表达出更多的信息(比如:一个数、一个句子等),每种高级语言在这基础之上都定义(内置)了自己的数据类型。

啰嗦一哈:「位」(bit)是数据存储的最小单位,每个0或1就是一位(bit),8bit称为一个字节(Byte),我们常说32位电脑,也是指 CPU 一次最多能处理 32 位数据的意思。

Go 语言中的数据类型分为四类:基础类型、复合类型、引用类型和接口类型

  • 基础类型,包括:数字、字符串和布尔型。
  • 复合类型,包括:数组、结构体。
  • 引用类型,包括:指针、切片、字典、函数、通道

本小节我们先从基础类型聊起,我们先认识一下全部的基础数据类型,如下图:

类型描述
bool布尔
string字符
int int8 int16 int32 int64有符号整数
uint uint8 uint16 uint32 uint64 uintptr无符号整数
float32 float64浮点数
complex64 complex128复数
byteuint8 的别名
runeint32 的别名(代表一个 Unicode 码)

关于 Unicode 编码,将在字符串那一章节详细讲解。

变量

在 Go 语言中,定义变量有多种方式,每一种都有其存在的意义,而对于数值类型的值范围大小,将在下一章节再讨论,本节我们的目标是对基础类型定义,看招吧:

单变量定义

方式一:声明变量并赋值(手动指定类型)

// 语法:var 变量名字 类型 = 表达式
// 示例:
var name string = "二狗子"
var money float64 = 5.21

方式二:声明变量并赋值(自推导类型)

// 语法:var 变量名字 = 表达式
// 示例:
var age = 18

方式三:声明变量并赋值(简短写法),使用 := 符号(自推导类型)

// 语法:变量名字 := 表达式
// 示例:
trueName := "李二狗"

以上说了三种变量定义的方式,但是注意几点:

  • 变量一旦定义,必须在程序中使用否则编译不通过
  • 同一个变量名,不能重复声明或定义,可通过赋值符号 = 改变其变量值
  • 简短写法(:=)这种方式仅可以用于函数内部,声明局部变量,而 var 则不受限制

如果只声明,不为其主动赋值(系统会为其初始化默认值)如下:

// 语法:var 变量名 类型
// 示例:
var name string     // ""
var age int         // 0
var isBabe bool     // false

课后一练:

  1. 使用三种方式,分别定义如下二个变量:
  • 变量名为:china 值为:中华人民共和国
  • 变量名为:thisYear 值为:2020
点击预览代码
// 方式一
var china string = "中华人民共和国"
var thisYear int = 2020
// 方式二
var china = "中华人民共和国"
var thisYear = 2020
// 方式三
china := "中华人民共和国"
thisYear := 2020

多变量定义

弄明白了,单个变量的声明定义,那么同时定义多个变量就好懂了,如下:

// 写法一:一次声明多个变量并赋值(相同类型)
var num1, num2, num3 int = 1, 2, 3
// 写法二:一次声明多个变量并赋值(不同类型)
var (
    a string = "Hello"
    b int = 20
    c bool = true
)
// 写法三:使用类型自推导写法(省略类型)
var num4, str5 = 4, "55"
// 写法四:多个变量定义(简短写法)
num6, num7 := 6, 7
点击预览完整示例
// gobing.io/ch2/variable.go
package main

import "fmt"

func main() {
  var num1, num2, num3 int = 1, 2, 3
  // 写法二:一次声明多个变量并赋值(不同类型)
  var (
      a string = "Hello"
      b int    = 20
      c bool   = true
  )
  // 写法三:使用类型自推导写法(省略类型)
  var num4, str5 = 4, "55"
  // 写法四:多个变量定义(简短写法)
  num6, num7 := 6, 7
  fmt.Println(num1, num2, num3)           // 1 2 3
  fmt.Printf("a 类型:%T 值:%s\n", a, a)   // a 类型:string 值:Hello
  fmt.Printf("b 类型:%T 值:%d \n", b, b)  // b 类型:int 值:20
  fmt.Printf("c 类型:%T 值:%t \n", c, c)  // c 类型:bool 值:true
  fmt.Printf("num4 类型:%T 值:%d \n", num4, num4) // num4 类型:int 值:4
  fmt.Printf("str5 类型:%T 值:%v \n", str5, str5) // str5 类型:string 值:55
  fmt.Println(num6, num7) // 6 7

}

例子中使用到了打印方法 PrintlnPrintf,这两打印方法是包 fmt 中的,所以再使用时,需要先 import "fmt" 导入此包,即第二行代码,调用方法则是用点(.)的方式,如:fmt.Println()

  • Println 打印输出后会自动带上换行符

  • Printf 中 %d%T%s%v是转换字符,意思是使用后面的变量,按照转换字符对应的类型一一进行替换

  • %d 表:打印 int 型

  • %s 表:打印 string 型

  • %T 表:打印变量的类型

  • %v 表:将任意变量以易读的形式打印出来

了解更多转换字符 见附录一

变量交换

Go 中变量交换技巧(无需定义中间临时变量):

var num1 int = 10
var num2 int = 20
num1, num2 = num2, num1 // 交换 num1 和 num2 的值
fmt.Println(num1, num2) // 20 10

变量默认值

如果只声明变量,并不为其赋值,将使用系统默认值,以下是四种类型的默认值:

var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s) // 0 0 false ""

%q 意思:是告诉 Printf 函数输出带上引号的字符串

常量

常量:一旦值被赋值(编译期计算,而不是运行期),其值不会被改变,常量可以是字符、字符串、布尔或数字类型的值,

常量的定义和变量类似,只不过是使用 const 关键字:

声明单个常量:

const pi = 3.1415926
fmt.Printf("%T %v\n", pi, pi) // float64 3.1415926

声明多个常量:

const (
  e = 2.7182818
  p = 3.1415926
)
fmt.Println(e, p) // 2.7182818 3.1415926

未定义常量的值时,默认取上一个类型和值

const (
  a = 1
  b
  c = 2
  d
)
fmt.Printf("%T a=%[1]d b=%d c=%d d=%d", a, b, c, d) // int a=1 b=1 c=2 d=2

注:% 之后的[1] 意思是告诉 Printf 函数再次使用第一个数进行格式化输出(这样可省去了一个参数的传递)

iota

Go 中没有枚举类型,iota 作为常量的计数器(默认从 0 开始),可以完成枚举的作用。

我们先看一个简单的例子:

// 定义类型别名
type Weekday int
const (
  Sunday Weekday = iota
  Monday
  Tuesday
  Wednesday
  Thursday
  Friday
  Saturday
)
fmt.Println(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
// Output: 0 1 2 3 4 5 6

如果破坏了 iota 的连续性,后面的常量将不再自动计数,如下:

const (
  num1 = iota
  num2
  num3 = 30
  num4
)
fmt.Println(num1, num2, num3, num4) // 0 1 30 30

iota 更高级一点的用法,可以是一个表达式,如下(定义计算机存储单位常量):

const (
  _   = 1 << (10 * iota)
  KiB  // 1024
  MiB  // 1048576
  GiB  // 1073741824
  TiB  // 1099511627776
  PiB  // 1125899906842624
  EiB  // 1152921504606846976
  //ZiB
  //YiB
)
fmt.Println(KiB, MiB, GiB, TiB, PiB, EiB)

End ,变量与常量本章节就介绍到这里了,下章我们了解一下 Go 中的指针与运算符。