Go基础系列 | 4. 常量及运算符

2021年11月26日 阅读数:4
这篇文章主要向大家介绍Go基础系列 | 4. 常量及运算符,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

 

学到什么

  1. 什么是常量?web

  2. 如何定义常量?数据库

  3. 常量和变量有什么不一样?编程

  4. 如何使用常量?编程语言

  5. 有哪些运算符?spa

  6. 如何使用运算符?指针

  7. 运算符的优先级?code

常量

1. 概念

常量的值在程序运行期间是不能改变的,而变量的值在运行期间是能够改变的。blog

举个实际使用到常量的几个场景:开发

  • web开发时,根据业务定义的错误码字符串

  • 程序的发行版本号

  • 数据库链接池数量(若是不经过配置文件时)

  • 等等

在使用时,只要你肯定在程序运行期间不改变它的值,就可使用常量。

2. 定义

常量的定义格式: const 常量名 [常量类型] = 常量值

[常量类型] 能够省略,编译器会根据值来推导类型。

// 显示定义
const b string = "abc"

// 隐式定义
const b = "abc"

对于常量值的数据类型,只能够定义为布尔型、数字型(整数型、浮点型和复数)和字符串型。

// 默认 bool
const isOpen = true

// 默认 rune,int32 的别名
const MyRune = 'r'

// 默认 int
const limit= 12

// 默认 float64
const rate= 29.87

// 默认 complex128
const complexNumber = 1 + 2i

// 默认 string
const hotelName = "Gopher Hotel"

定义时还有两种写法。

// 第一种,常量块的形式
const (
    isOpen = true
    MyRune = 'r'
)

// 第二种,并行赋值
const limit, rate = 1229.87

注:第一种“常量块”的形式是实际中用的比较多的。

3. 隐式定义不限制

是什么意思呢?意思就是我在定义时,省略了数据类型后,值的大小是不受限制,即不会产生溢出。

const num = 111111111111111111111111111111111111111111111

若是显示定义数字型常量,它必然会有存储空间大小限制。好比:定义一个int64 类型,它的最大值为 9223372036854775807,但若是超过这个最大值,就会溢出,程序天然会抛异常,还原以下:

// 文件名 main.go
package main

import "fmt"

func main() {
    // 最大值 + 1
    const num int64 = 9223372036854775808
}

运行后输出如下结果:

go run main.go
# 输出
.\main.go:6:8: constant 9223372036854775808 overflows int64

4. iota 用法

iota是 Go 语言中的一个关键字,先看代码,再解释。

const (
    a = iota  // a = 0
    b         // b = 1
    c         // c = 2
    d = 5     // d = 5   
    e         // e = 5
)

iota 从0开始,每增长新的一行就会自动加一,直到遇到新的赋值或从新声明一个 const块iota 重置为0。

iota 也能够参加运算,举几个例子就明白了。

// 从1开始自动加一
const (
    Apple = iota + 1 // Apple=1 
    Cherimoya        // Cherimoya=2 
    Elderberry       // Elderberry=3
)

// 并行赋值两个常量,iota 只会在第一行增加一次
// 而不会由于使用了两次就增加两次
const (
    Apple, Banana = iota + 1iota + 2 // Apple=1 Banana=2
    Cherimoya, Durian   // Cherimoya=2 Durian=3
    Elderberry, Fig     // Elderberry=3, Fig=4
)

// iota参与位运算
const (
    Open = 1 << iota  // 0001
    Close             // 0010
    Pending           // 0100
)

运算符

1. 分类

  • 算术运算符:+(加),-(减),*(乘),/(除),%(求余),++(自增),--(自减)

  • 比较运算符:==(等于),!=(不等于),>(大于),<(小于),  >=(大于等于), <=(小于等于)

  • 赋值运算符:=(右值赋值给左侧), += , -=, *=, /=,%=,  &=,  |=,  ^=,  >>=,  <<= (前面的都是左侧值和右侧值运算后再赋值给左侧)

  • 位运算符:&(按位与),|(按位或),^(按位异或/取反),>>(右移位),<<(左移位)

  • 逻辑运算符:&&(与),||(或),!(非)

  • 其余运算符:&(取变量地址),*(指针)

2. 算数运算符

初始化 a 和 b 两个变量进行运算,使用以下:

a := 10
b := 3

fmt.Println("a+b=", a+b)  // a+b= 13
fmt.Println("a-b=", a-b)  // a-b= 7
fmt.Println("a*b=", a*b)  // a*b= 30
fmt.Println("a/b=", a/b)  // a/b= 3

// 不支持 ++a
a++
fmt.Println("a++=", a)  // a++= 11
// 错误写法:fmt.Println(a++),
// 必须通过运算后才可以使用, 自减也是同样

// 不支持 --a
a--
fmt.Println("a--=", a)  // a--= 10

注:自增和自减去只支持后置的++或--。

3. 比较运算符

初始化 a 和 b 两个变量,进行比较,使用以下:

a := 10
b := 3

fmt.Println("a==b:", a == b)  // a==b: false
fmt.Println("a!=b:", a != b)  // a!=b: true
fmt.Println("a>b:", a > b)    // a>b: true
fmt.Println("a>=b:", a >= b)  // a>=b: true
fmt.Println("a<b:", a < b)    // a<b: false
fmt.Println("a<=b:", a <= b)  // a<=b: false

4. 赋值运算符

初始化 a 变量 为10,使用以下:

// 将 10 赋值给 a 变量
var a = 10  // 简写方式:a := 10

// 在10的基础上加2
// 等价于 a = a + 2
a += 2  // 12

// 在12的基础上减3
// 等价于 a = a - 3
a -= 3  // 9

// 在9的基础上乘以2
// 等价于 a = a * 2
a *= 2  // 18

// 在18的基础上除以3
// 等价于 a = a / 3
a /= 3  // 6

// 在6的基础上对4求余
// 等价于 a = a % 4
a %= 4  // 2

注:&=、|=、^=、>>=、<<= 运算符就省略不写了(不是懒,感受太啰嗦了),看懂下面的位运算符的意思,照上面的类比理解就明白了。

5. 位运算符

初始化  a 和 b 两个变量进行运算,前提要明白十进制如何转化为二进制,使用以下:

a := 4  // 二进制: 0100
b := 3  // 二进制: 0011

// 按位与
// 对应位都为1时,结果为1
a & b  // 0

// 按位或
// 对应位有一个为1时,结果为1
a | b  // 7

// 按位异或
// 对应位相同时为0,不相同时为1
a ^ b  // 7

// 按位取反
// 取反后变成1100, 最高位1表明负数
^b  // -4

// 按位右移
// 将二进制 0100 向右移动一位变成 0010
a >> 1  // 2

// 按位左移
// 将二进制 0100 向左移动一位变成 1000
a << 1  // 8

注:按位异或和按位取反”的运算符是同样的,区别在于“操做数”数量上,按位异或操做数为两个,按位取反操做数是一个。

6. 逻辑运算符

逻辑运算符只能应用到 bool 类型上,初始化 a 和 b 两个 bool 值,使用以下:

a := true
b := false

// 与运算,都为 true 时,结果为 true
a && b  // false

// 或运算,有一个为 true 时,结果为 true
a || b // true

// 非运算,为 true 时,结果为 false
// 反之,为 false 时,结果为 true
!a  // false
!b  // true

7. 其余运算符

就剩下两个运算符的使用了,往下看:

// 变量地址
a := 1
fmt.Println(&a) // 0xc00000a9b0

// 指针变量,在变量地址前加个 * 表明取出值
p := &a
fmt.Println(*p)  // 1

8. 运算符优先级

优先级:表中优先级列数字越大优先级越高,规定了不一样优先级的结合顺序,举例以下:

// '*' 优先级 > '+' 优先级
// 等价于 a := (2 * 3) + 1
a := 2 * 3 + 1

结合性:表中结合性列中的“从左到右”和“从右到左”表示同优先级运算符的结合顺序,举例以下

// 从表中看到结合性是从左到右
// 等价于 a := (1 + 2) + 3 
a := 1 + 2 +3

总结

本篇讲解了“常量”和“运算符”的使用,若是掌握了其它编程语言,那重点看看常量怎么使用就行,尤为是 iota 关键字的使用,至于“运算符”语言之间都差很少,就能够偷懒不看了,有啥不懂的就在下方留言。