携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
一、Go 语言的运算符
运算符的分类
Go 中的运算符与其他语言中的运算符并无太大区别,主要也是包含了以下几种:
- 算数运算符:
+ - * / %(求余) ++ --
- 关系运算符:
== != > < >= <=
- 逻辑运算符:
&& || !
- 位运算符:
& | ^ << >>
- 赋值运算符:
= += -= *= /= %= &= |= ^= <<= >>=
- 其他运算符:
& *
func main() {
// 算数运算符
a := 9
b := 2
res1 := a / b
res2 := a % b
fmt.Printf("%v, %T\n", res1, res1)
fmt.Printf("%v, %T\n", res2, res2)
// 字符串的比较
c := "abcd"
d := "abaf"
res3 := c > d
fmt.Printf("%v, %T\n", res3, res3)
// 字符串的比较还可以调用 strings 标准库下的 Compare 函数
fmt.Println(strings.Compare("abcd", "abaf"))
}
执行上述代码,输出结果如下:
4, int
1, int
true, bool
1
字符串比较时会逐个字符比较,一旦有结果就返回,字符串比较时使用运算符比较返回的结果是布尔值,使用 strings 标准库下的 Compare 函数比较返回的是 1、0、-1。
&&
:逻辑与运算符;如果两个操作数都非零,则条件变为真||
:逻辑或运算符;如果任何两个操作数是非零,则条件变为真!
:逻辑非运算符;使用反转操作数的逻辑状态。如果条件为真,那么逻辑非操后结果为假
func main() {
var zulu bool = true
var yankee bool = false
fmt.Printf("zulu && yankee 的结果为:%v\n", zulu && yankee)
fmt.Printf("zulu || yankee 的结果为:%v\n", zulu || yankee)
fmt.Printf("!(zulu && yankee) 的结果为:%v\n", !(zulu && yankee))
}
执行上述代码,输出结果为:
zulu && yankee 的结果为:false
zulu || yankee 的结果为:true
!(zulu && yankee) 的结果为:true
位运算符对整数在内存中的二进制位进行操作,将两个二进制数每个位置上的数进行按位与(&)、按位或(|)、按位异或(^)操作
&:按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。两数都是 1 时结果为 1,其他为 0。
|:按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或,两个数中有一个为 1 时结果为 1, 其他为 0。
^按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。
func main() {
fmt.Println(60 & 80)
fmt.Println(60 | 80)
fmt.Println(60 ^ 80)
}
执行上述代码,输出结果为:
16
124
108
赋值运算符分为两步,先执行等号前的运算,然后在进行赋值。
指针运算符包含以下两个:
- &:返回变量存储地址
- *:指针变量。
运算符的优先级
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。
逗号运算符 > 赋值运算符 > 逻辑或 > 逻辑与 > 按位或 > 按位异或 > 按位与 > 相等/不等 > 关系运算符 > 位移运算符 > 加法/减法 > 乘法/除法/取余 > 单目运算符 > 后缀运算符。
实际编码中可以通过使用括号来临时提升某个表达式的整体运算优先级。
二、格式化输出
fmt 标准库
在之前的文章中已经多次用到的 fmt 标准库 下的标准输出函数 Println()
和格式化输出 Printf()
函数,在这篇文章中将介绍 fmt 标注库
中的格式输入和输出。
Package fmt implements formatted I/O with functions analogous to C's printf and scanf. The format 'verbs' are derived from C's but are simpler.
fmt 标准库实现了类似 C 语言 printf 和 scanf 的格式化 I/O,比 C 语言更加简单。
通用(缺省)占位符
%v 值的默认格式表示
%+v 类似%v,但输出结构体时会添加字段名
%#v 值的Go语法表示
%T 值的类型的Go语法表示
%% 百分号
格式化输出需要用到 fmt 包下的 Printf()
函数,在之前的文章已经使用过 %v
占位符,该占位符可以表示变量的值。
func main() {
name := "peter"
age := 18
fmt.Printf("I am %v, and %v years old", name, age)
}
执行上述代码,输出结果如下:
I am peter, and 18 years old
如果再添加一个 #
既变为 %#v
时,字符串的输出则会自动加上双引号。
// 其余代码不变
fmt.Printf("I am %#v, and %#v years old", name, age)
执行上述代码,输出结果如下:
I am "peter", and 18 years old
%#v
会按照 Go 语法打印出变量的值,既变量值在 Go 代码中是什么形式,打印出来就是什么形式。
除了 %v
之外还有 %T
,可以输出变量的类型。
// 其余代码不变
fmt.Printf("name 变量的类型:%T, age 变量的类型:%T", name, age)
执行上述代码,输出结果如下:
name 变量的类型:string, age 变量的类型:int
%v
、%#v
、%T
、%+v
、%%
占位符使用时是没有类型限制的,任何类型的变量都可以使用这三个占位符进行表示,也称为缺省。
整型占位符
对于整数类型 int 的来说,有以下几种占位符:
%b 表示为二进制
%c 该值对应的unicode码值
%d 表示为十进制
%o 表示为八进制
%q 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x 表示为十六进制,使用a-f
%X 表示为十六进制,使用A-F
%U 表示为Unicode格式:U+1234,等价于"U+%04X"
func main() {
name := "peter"
age := 18
fmt.Printf("I am %v, and %d years old\n", name, age)
fmt.Printf("I am %v, and %+d years old\n", name, age)
fmt.Printf("I am %v, and %4d years old\n", name, age)
fmt.Printf("I am %v, and %-4d years old\n", name, age)
fmt.Printf("I am %v, and %b years old\n", name, age)
fmt.Printf("I am %v, and %o years old\n", name, age)
fmt.Printf("I am %v, and %x years old\n", name, 12138)
}
执行上述代码,输出结果如下:
I am peter, and 18 years old
I am peter, and +18 years old
I am peter, and 18 years old
I am peter, and 18 years old
I am peter, and 10010 years old
I am peter, and 22 years old
I am peter, and 2f6a years old
上述代码中使用到了 %4d
和 %-4d
,它们分别表示右对齐和左对齐。