Go学习笔记(一):语法基础1
2020-04-08 11:50:281.编写第一个Go程序
首先我们编写一个Hello World程序
package main //包,表明代码所在的模块(包)
import "fmt" //引⼊代码依赖
//功能实现
func main() {
fmt.Println("Hello World!")
}
应用程序入口
1.必须是 main 包:package main
2.必须是 main ⽅法:func main()
3.⽂件名不⼀定是main.go
main函数的返回值和参数
与其他主要编程语⾔的差异
- Go 中main函数不⽀持任何返回值
- 需要通过os.Exit来返回状态
- 同样main 函数不⽀持传⼊参数 func main(
arg []string) - 在程序中直接通过os.Args获取命令⾏参数
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) > 1 {
fmt.Println("Hello World", os.Args[1])
}
os.Exit(-1)
}
2. 变量与常量
在开始前先介绍一下go语言如何编写一个测试代码,方便编写测试程序。go语言只要满足下面2点规则就能运行测试
- 源码⽂件以_test结尾:xxx_test.go
- 测试⽅法名以Test开头:func TestXXX(t *testing.T) {…}
接下来我们编写一个Fibonacci 数列来介绍变量的定义
数列:1, 1, 2, 3, 5, 8, 13, ….
import (
"testing"
)
func TestFibList(t *testing.T) {
// 1. 变量声明一般方法
// var a int = 1
// var b int = 1
// 2. 统一一起声明,注意变量b 去掉了类型定义,系统可以根据赋值自动判断
// var (
// a int = 1
// b = 1
// )
// 3. 方法3,快捷声明与赋值(推荐)
a := 1
b := 1
t.Log(a)
for i := 0; i < 5; i++ {
t.Log(" ", b)
tmp := a
a = b
b = tmp + a
}
}
在⼀个赋值语句中可以对多个变量进⾏同时赋值。利用go语言这个特性,如果要实现变量的值交换,有更便捷的写法,如下:
func TestExchange(t *testing.T) {
a := 1
b := 2
// 1. 其他语言交换变量需要先用一个临时变量来实现,而go语言可以直接交换
// tmp := a
// a = b
// b = tmp
// 2. go语言的直接赋值语法,实现变量值的交换
a, b = b, a
t.Log(a, b)
}
go与其他主要编程语⾔的差异
可快速设置连续值
const (
Monday = iota + 1
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
)
下面代码实现快速对常量进行位赋值 1、2、4
const (
Open = 1 << iota
Close
Pending
)
4.数据类型
go语言支持如下数据类型
类型 |
---|
bool |
string |
int int8 int16 int32 int64 |
uint uint8 uint16 uint32 uint64 uintptr |
byte // alias for uint8 |
rune // alias for int32,represents a Unicode code point |
float32 float64 |
complex64 complex128 |
类型转换
与其他主要编程语⾔的差异
- Go 语⾔不允许隐式类型转换
- 别名和原有类型也不能进⾏隐式类型转换
类型的预定义值
- math.MaxInt64
- math.MaxFloat64
- math.MaxUint32
指针类型
与其他主要编程语⾔的差异
- Go 语⾔不⽀持指针运算
- string 是值类型,其默认的初始化值为空字符串,⽽不是 nil
其他语言中我们判断string不为空需要判断 str !=null && str != "",而go语言string默认值就是“”, 所以只需要如下代码判断,且默认的长度为0, 其他强类型语言对空的string取长度可能会出现空异常
func TestString(t *testing.T) {
var s string
if(s == "") {
t.Log("*" + s + "*") //初始化零值是“”
}
t.Log(len(s))
}
5 运算符
算术运算符
运算符 | 描述 | 实例 |
---|---|---|
+ | 相加 | A + B 输出结果 30 |
- | 相减 | A - B 输出结果 -10 |
* | 相乘 | A * B 输出结果 200 |
/ | 相除 | B / A 输出结果 2 |
% | 求余 | B % A 输出结果 0 |
++ | ⾃增 | A++ 输出结果 11 |
-- | ⾃减 | A-- 输出结果 9 |
Go 语⾔没有前置的 ++,- -,(++a)
比较运算符
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False | (A == B) 为 False |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False | (A != B) 为 True |
> | 检查左边值是否⼤于右边值,如果是返回 True 否则返回 False | (A > B) 为 False |
< | 检查左边值是否⼩于右边值,如果是返回 True 否则返回 False | (A < B) 为 True |
>= | 检查左边值是否⼤于等于右边值,如果是返回 True 否则返回 False | (A >= B) 为 False |
<= | 检查左边值是否⼩于等于右边值,如果是返回 True 否则返回 False | (A <= B) 为 True |
⽤ == ⽐较数组
- 相同维数且含有相同个数元素的数组才可以⽐较
- 每个元素都相同的才相等
func TestCompareArray(t *testing.T) {
a := [...]int{1, 2, 3, 4}
b := [...]int{1, 3, 2, 4}
// c := [...]int{1, 2, 3, 4, 5}
d := [...]int{1, 2, 3, 4}
t.Log(a == b)
//t.Log(a == c) //数组长度不一致,不能比较
t.Log(a == d)
}
逻辑运算符
运算符 | 描述 | 实例 |
---|---|---|
&& | 逻辑 AND 运算符。如果两边的操作数都是 True,则条件 True,否则为 False | (A && B) 为 False |
! | 逻辑 NOT 运算符。如果条件为 True,则逻辑 NOT 条件 False,否则为 True | !(A && B) 为 True |
位运算符
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符"&"是双⽬运算符。其功能是参与运算的两数各对应的⼆进位相与 | (A & B) 结果为 12, ⼆进制为 0000 1100 |
按位或运算符" | ||
^ | 按位异或运算符"^"是双⽬运算符。其功能是参与运算的两数各对应的⼆进位相异或,当两对应的⼆进位相异时,结果为1。(A ^ B) 结果为 49, ⼆进制为 0011 0001 | (A ^ B) 结果为 49, ⼆进制为 0011 0001 |
<< | 左移运算符”<<"是双⽬运算符。左移 n 位就是乘以 2 的 n 次⽅。其功能把"<<"左边的运算数的各⼆进位全部左移若⼲位,由"<<"右边的数指定移动的位数,⾼位丢弃,低位补 | A << 2 结果为 240 ,⼆进制为 1111 0000 |
>> | 右移运算符”>>"是双⽬运算符。右移 n 位就是除以 2 的 n 次⽅。其功能是把">>"左边的运算数的各⼆进位全部右移若⼲位,">>"右边的数指定移动的位数 | A >> 2 结果为 15 ,⼆进制为 0000 1111 |
与其他主要编程语⾔的差异
&^ 按位置零
1 &^ 0 -- 1
1 &^ 1 -- 0
0 &^ 1 -- 0
0 &^ 0 -- 0
&^ 当右边为0是,保留左边的值;当右边为1时,结果为0。这种运算可以用于清除权限。如下代码:
const (
Readable = 1 << iota
Writable
Executable
)
func TestBitClear(t *testing.T) {
a := 7 //0111
a = a &^ Readable
a = a &^ Executable
t.Log(a&Readable == Readable, a&Writable == Writable, a&Executable == Executable)
}
6、结构化程序
for
Go 语⾔仅⽀持循环关键字 for
n := 0
for n < 5 {
n++
fmt.Println(n)
}
if
- condition 表达式结果必须为布尔
- ⽀持变量赋值
if var declaration; condition{
//code to be executed if condition is true
}
switch
- 条件表达式不限制为常量或者整数;
- 单个 case 中,可以出现多个结果选项, 使⽤逗号分隔;
- 与 C 语⾔等规则相反,Go 语⾔不需要⽤break来明确退出⼀个 case;
- 可以不设定 switch 之后的条件表达式,在此种情况下,整个 switch 结构与多个 if…else… 的逻辑作⽤等同
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
//break
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
switch {
case 0 <= Num && Num <= 3:
fmt.Printf("0-3")
case 4 <= Num && Num <= 6:
fmt.Printf("4-6")
case 7 <= Num && Num <= 9:
fmt.Printf("7-9")
}