Go语言基础 -- 变量,常量,运算符,下划线

1. 标准API官方文档

https://studygolang.com/pkgdoc

2. 常用符号

1. 1 转义字符(escape char)

1.\t    一个制表位,实现对齐的功能
2.\n    换行符
3.\\    一个\
4.\"    一个"
5.\r    一个回车 fmt.Println("hello\rgo")  # 字符串必须是双引号

1.2 注释符

"//"    //注释一行 

"/*  */"   //注释多行,不允许嵌套

3. 标识符(变量名)

3.1 什么是标识符

  1. Golang 中对各种变量,方法等命名时使用的字符序列(字符串)称为标识符
  2. 凡是自己可以取名字的地方都叫标识符

3.2 命名规则

  1. 由26个英文字母大小写,0-9,_组成
  2. 数字不可以开头
  3. 严格区分大小写
  4. 标识符不能包含空格
  5. 下划线"_"本身在Go中是一个特殊的标识符,称为空标识符,可以代表任何其他的标识符,但是它对应的值会被忽略(比如:忽略某个返回值),所以仅能被作为占位符使用,不能作为标识符使用
  6. 不能以系统保留关键字(25个)作为标识符,比如break,if等等

1. 保留关键字

2. 预定义标识符

3. 案例

4. 标识符注意事项

  1. 包名:包(package)的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库冲突
  2. 变量名,函数名,常量名,使用驼峰体
  3. 如果变量名,函数名,常量名首字母大写,则可以被其他包访问,如果首字母小写,则只能在本包中使用(注:简单理解,首字母大写是共有的,首字母小写是私有的)

3. 变量声明

变量是由,变量名,值以及数据类型组成的一个整体

3.1 var 定义变量

1. 语法格式

// 1.先声明后赋值
var 变量名 类型
变量名 = 值

// 2. 声明的同时赋值
var 变量名 类型 = 值

2. 示例

// 1.先声明后赋值
var age int 
age = 18


// 2. 声明的同时赋值

var age int = 18

3. 执行流程

var age int  // 声明变量,在内存中请求一块数据空间, age 指向该空间,默认值为0
age = 10  // 给变量赋值,在内存中找到 age 指定的空间,将之前的默认值0重新赋值为10

4. 注意事项:

1. 变量表示内存中的一个存储区域
2. 该区域有自己的名称(变量名)和类型(数据类型)
3. golang变量使用的三种方式:
    1).指定变量类型,声明后若不赋值,则使用默认值

3.2 类型推导

1. 语法格式

var 变量名 = 值

2. 示例

var num = 10.22  // 编译器根据值类型,自动定义变量类型

3.3 简写方式

1. 语法格式

变量名 := 值

2. 示例

num := 10.22  

3.注意事项:

1. `:=` 只能用来定义局部变量

3.4 多变量声明

1. 语法格式

// 多变量赋值相同类型,并根据给定的类型赋默认值
var 变量名1,变量名2,变量名3 类型   			

// 多变量赋值不同类型,并根据给定的类型赋默认值
var 变量名1,变量名2,变量名3 类型1,类型2,类型3   

// 类型推导
变量名1,变量名2,变量名3 := 类型1,类型2,类型3

2. 示例

// 多变量赋值相同类型,并根据给定的类型赋默认值
var n1,n2,n3 int			

// 多变量赋值不同类型,并根据给定的类型赋默认值
var n1,n2,n3 = 100,"tom",888   

// 类型推导
n1,n2,n3 := 100,"char",800

3.5 声明多个全局变量

1. 一次性声明多个全局变量

package main

var n1 = 100
var n2 = "name"
var n3 = 1.2

func main(){
    ...
}

2.简写方式

var (
  n1 = 100
  n2 = "name"
  n3 = 1.2
)

3.6 多次赋值相同类型

package main

func main(){
    var age int = 18
    age = 19
    age = 16
    age = 1.2  // 这里会报错,因为赋值不能改变原数据类型
}

3.7 相同作用域变量名不能重名

package main 

func main(){
    var age = 18
    
    var age = 33  // 这里会报错,相同作用域不允许有相同的变量名存在
}

4. 常量定义

1.语法格式

// type可以省略
const identifier [type] = value     

2. 示例

简单写法

const(
    a = 1
    b = 2
)

专业写法

示例一:

const (
    a = iota   // 表示给a赋值为0,iota表示以下常量为自增常量
    b          // 1
    _          // 忽略2, - 表示忽略,类似 python 的pass
    c          // 3
)

示例二:

package main

import "fmt"

const (
	_  = iota
	KB = 1 << (10 * iota)
	MB = 1 << (10 * iota)
	GB = 1 << (10 * iota)
	TB = 1 << (10 * iota)
	PB = 1 << (10 * iota)
)

func main() {
	fmt.Println(KB, MB, GB, TB, PB)
}

// 1024 1048576 1073741824 1099511627776 1125899906842624

示例三:

 const (
     a, b = iota + 1, iota + 2 //1,2 表示a从 1+0 开始递增, b从 2+0 开始递增
     c, d                      //2,3
     e, f                      //3,4
)

注意事项

  1. 常量使用const修饰
  2. 常量在定义的时候,必须初始化
  3. 常量不能修改
  4. 常量只能装饰bool,数值类型(int,float系列),string
  5. golang 中没有常量名必须大写的规范
  6. 通过首字母的大小写来控制常量的访问范围,如大写就是外部文件也可以访问到此常量

5. 运算符

5.1 算数运算符

5.1.1 算数运算符种类

算术运算符是对数值类型的变量进行运算的,比如:加减乘除,在Go程序中使用的非常多

运算符 运算 范例 结果
+ 正号 +3 3
- 负号 -4 -4
+ 5 + 5 10
- 6 - 4 2
* 2 * 3 6
/ 5 / 5 1
% 取余 7 % 5 2
++ 自增 a = 2 a++ a = 3
-- 自减 a = 2 a-- a = 1

5.1.2 除法

在Go语言中,如果运算的数都是整数,name除后,去掉小数部分,只保留整数部分(不会四舍五入),如果希望保留小数部分,则需要浮点数参与运算

// 例如:
10 / 4 = 2 
10.0 / 4 = 2.5

5.1.3 取余

公式: a % b = a - a / b * b

package main

import "fmt"

func main() {
	fmt.Println("7  % 5 = ", 7%5)    // 7  % 5 =  2
	fmt.Println("-7 % 5 = ", -7%5)   // -7 % 5 =  -2
	fmt.Println("7 % -5 = ", 7%-5)   // 7 % -5 =  2
	fmt.Println("-7 % -5 = ", -7%-5) // -7 % -5 =  -2
}

5.1.4 注意事项

  1. 对于除号 / ,它的整数除和小数除是有区别的,整数之间做除法时,只保留整数部分而舍弃小数部分
  2. 当对一个数取模(取余)时,可以等价于a%b = a-a/b*b,这是取模的本质运算
  3. 在Go语言中,++(自增)和--(自减) 是单独的语句,并不是运算符,不能这样使用 b:=a++或者b:=a--
  4. ++--只能写在变量的后面,不能写在变量的前面
  5. Golang的设计者去掉 c/java 中的自增自减的容易混淆的写法,让Golang更加简洁,统一(强制性的)

练习

1.假如还有97天放假,97天是多少星期多少天?

package main

import "fmt"

func main() {
	var num int = 97
	var wek int = num / 7
	var day int = num % 7
	fmt.Printf("还有%v星期零%v天",wek,day)
}

2.定义一个变量保存华氏摄氏度,华氏摄氏度转换摄氏温度的公式为:5/9*(华氏温度-100),求出华氏温度265对应的摄氏温度

package main

import "fmt"

func main() {
	var num int = 168
	var new_num float64
	new_num = 5.0 / 9 * float64(num -100)
	fmt.Printf("华氏温度%v,的摄氏温度为%v",num,new_num)

}

5.2 赋值运算符

5.2.1 赋值运算符种类

赋值运算符就是将某个运算后的值,赋值给指定的变量

运算符 描述 实例
= 简单的赋值运算符,将一个表达式的值赋给一个左值 C = A + B 将 A + B 表达式的结果赋值给 C
+= 相加后再赋值 C += A 等于 C = C + A
-= 相减后再赋值 C -= A 等于 C = C - A
*= 相乘后再赋值 C *= A 等于 C = C * A
/= 相除后再赋值 C /= A 等于 C = C / A
%= 求余后再赋值 C %= A 等于 C = C % A
<<= 左移后赋值 C <<= 2 等于 C = C << 2
>>= 右移后赋值 C >>= 2 等于 C = C >> 2
&= 按位与后赋值 C &= 2 等于 C = C & 2
^= 按位异或后赋值 C ^= 2 等于 C = C ^ 2
|= 按位或后赋值 C |= 2 等于 C = C | 2

5.2.2 注意事项

  1. 运算顺序为从右至左
  2. 赋值运算符的左边,只能是变量,右边可以是变量,表达式,常量值
  3. 赋值运算符等价于以下效果,如: a += 3 等价于 a = a + 3

5.3 比较(关系)运算符

5.3.1 比较运算符种类

运算符 描述
== 检查两个值是否相等,如果相等返回 True 否则返回 False。
!= 检查两个值是否不相等,如果不相等返回 True 否则返回 False。
> 检查左边值是否大于右边值,如果是返回 True 否则返回 False。
>= 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。
< 检查左边值是否小于右边值,如果是返回 True 否则返回 False。
<= 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。

5.3.2 注意事项

  1. 关系运算符的结果都是bool型,要么是true要么是false
  2. 关系表达式经常用在 if 结构的条件中或循环结构的条件中

5.4 逻辑运算符

5.4.1 逻辑运算符种类

用于链接多个条件(一般来说就是关系表达式),最终的结果也是一个bool

运算符 描述 实例
&& 逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。 (A && B) 为 False
ll 逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。 (A || B) 为 True
! 逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。 !(A && B ) 为 True

5.4.2 注意事项

  1. &&也叫短路与,如果第一个条件为false,则第二个条件不会判断,最终结果为fasle
  2. ||也叫短路或,如果第一个条件为true,则第二个条件不会判断,最终结果为true

5.5 位运算符

5.5.1 位运算符种类

位运算符对整数在内存中的二进制位进行操作。

运算符 描述
& 参与运算的两数各对应的二进位相与。(两位均为1才为1)
l 参与运算的两数各对应的二进位相或。(两位有一个为1就为1)
^ 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(两位不一样则为1)
<< 左移n位就是乘以2的n次方。“a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。
>> 右移n位就是除以2的n次方。“a>>b”是把a的各二进位全部右移b位

5.6 其他运算符

Go不支持三元运算符,go实现三元运算是if else

package main

import "fmt"

func testn(i,j,n int){
	if i > j {
		n = i
	} else {
		n = j
	}
	fmt.Println(n)
}

func main() {
	var n int
	// 传统的三元运算表达式
	// n = i>j ? i :j

	// Golang 中用判断来实现
	testn(10,12,n)

}

5.7 运算符的优先级

  1. 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序,如下表,上一行运算符总优先于下一行
  2. 只有弹幕运算符,赋值运算符是从右向左运算的

6. _下划线的作用

_是特殊标识符,用来忽略结果。

6.1 下划线在import中的作用

1. import 前加入下划线(如: import _ hello/imp)的作用

	当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import 引用该包。即使用【import _ 包路径】只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数。 示例:

2. 示例1:

import "database/sql"
import _ "github.com/go-sql-driver/mysql"

第二个import就是不直接使用mysql包,只是执行一下这个包的init()函数,把mysql的驱动注册到sql包里,然后程序里就可以使用sql包来访问mysql数据库了。

3. 示例2:

package main

import _ "./hello"

func main() {
    // hello.Print() 
    //编译报错:./main.go:6:5: undefined: hello
}

hello.go

package hello

import "fmt"

func init() {
    fmt.Println("imp-init() come here.")
}

func Print() {
    fmt.Println("Hello!")
}


// 输出结果:
imp-init() come here.

6.2 下划线在代码中的作用

1. 示例:

package main

import (
	"os"
)

func main() {
	buf := make([]byte, 1024)
    // 用来忽略结果,不在意第二个返回参数是什么
	f, _ := os.Open("/Users/***/Desktop/text.txt")
	defer f.Close()
	for {
		n, _ := f.Read(buf)
		if n == 0 {
			break
		}
		os.Stdout.Write(buf[:n])
	}
}

2. 在代码中的作用:

  1. 下划线的意思是忽略这个变量,比如os.Open(),返回值为*os.File,error,普通写法是 f,err := os.Open("xxxxxxx"),如果此时不需要知道返回的错误值,就可以用 f, _ := os.Open("xxxxxx"),如此则忽略了error变量
  2. 占位符,意思是那个位置本应赋给某个值,不需要这个值。所以就把该值赋给下划线,意思是丢掉不要。这样编译器可以更好的优化,任何类型的单个值都可以丢给下划线。这种情况是占位用的,方法返回两个结果,而你只想要一个结果。那另一个就用 "_" 占位,而如果用变量的话,不使用,编译器是会报错的
posted @ 2021-08-24 12:07  河图s  阅读(229)  评论(0)    收藏  举报