golang初识 和 变量,常量,iota
一、go语言与python
1. go语言
- go语言语法固定,没有那么多花里胡哨的写法,语法也简单。一共25个关键字,37个保留字
- 本身支持高并发,数据计算,做后端天然有优势。(云计算,区块链,网络服务行业,新兴的公司基本都用go语言)
- go为编译型语言(先编译再执行)、强类型语言(定义之好类型后的变量是不能赋值成别的类型的值的,比如刚开始定义的string类型,不能再后面赋值为其他类型的值,而python可以随意赋值),执行速度更快,go项目在不同操作系统上就会先被编译成不同格式的执行文件,如windows上被编译成
.exe 后缀
的可执行文件。 - go项目的整个程序只有main包(也就是主包)才是执行的入口,而python每一个py文件都可以是入口,都可以直接执行
- goland为go开发常用的ide,类似pycharm。vscode也可以开发go
2. python
-
开发效率高,所以周期短
-
爬虫加数据分析
-
人工智能
3. 下载安装
- 安装包下载地址为:https://golang.org/dl/ (需要FQ)。如果打不开可以使用这个地址:https://golang.google.cn/dl/。
(1)Linux安装
1、下载二进制包:go1.13.3.linux-amd64.tar.gz
2、将下载的二进制包解压至 /usr/local目录。
tar -C /usr/local -xzf go1.13.3.linux-amd64.tar.gz
3、将 /usr/local/go/bin 目录添加至PATH环境变量:
export PATH=$PATH:/usr/local/go/bin
(2)Windows安装
-
Windows 下可以使用 .msi 后缀(在下载列表中可以找到该文件,如go1.13.3.windows-amd64.msi)的安装包来安装。
-
默认情况下 .msi 文件会安装在 c:\Go 目录下。你可以将 c:\Go\bin 目录添加到 Path 环境变量中。添加后你需要重启命令窗口才能生效
(3)Mac安装
- Mac下直接双击go1.13.3.darwin-amd64.pkg,一路下一步安装即可
4. go语言的基本语法
-
package 后面跟的是包名,用来声明当前这个文件是属于哪个包。如果是属于main包,main包为整个程序的入口。
-
go语言在命令行的两种运行方式
-
先生成编译文件,再手动执行编译文件
go build 文件名.go
—————> windows下会把该文件打包成一个.exe
文件,再运行该.exe
文件
-
命令行直接执行
go run 文件名.go
命令即可(相当于对编译和执行命令的封装)
-
-
import 包名
用来导入的包 -
func main()
是整个程序的入口,没有参数。 -
在函数外部只能放置标识符(即 变量,常量,函数,类型)的声明
-
变量定义之后必须使用(包级别的变量可以不使用),否则报错(python中用不用都没事)
-
导的包也必须使用,不使用也报错(python中用不用都没事)
-
函数外的每个语句都必须以关键字开始(var、const、func等)
-
单行注释用
//
,多行注释用/**/
-
单引号、双引号、反引号的作用
-
单引号在go语言中表示golang中的rune(int32)类型,单引号里面是单个字符,对应的值为该字符对应的ASCII值
-
func main() { a := 'A' fmt.Println(a) } /* 输出: random@random-wz MINGW64 /c/GOPATH/src/Test $ go run main.go 65 */
-
-
双引号在go语言中双引号里面可以是单个字符也可以是字符串,双引号里面可以有转义字符,如
\n、\r
等,对应go语言中的string类型-
func main() { a := "Hello golang\nI am random_wz." fmt.Println(a) } /* 输出: random@random-wz MINGW64 /c/GOPATH/src/Test $ go run main.go Hello golang I am random_wz. */
-
-
反引号中的字符表示其原生的意思,在反引号中的内容可以是多行内容,不支持转义
-
func main() { a := `Hello golang\n: I am random_wz. Good.` fmt.Println(a) } /* 输出: random@random-wz MINGW64 /c/GOPATH/src/Test $ go run main.go Hello golang\n: I am random_wz. Good. */
-
-
5. 简单的go程序脚本
// 双斜杠,为单行注释
/* 多行注释 */
package main // 表示当前文件为main包,也就是主包,go的文件想要执行,必须要有个主包,整个程序的入口就是主包文件
import "fmt"
// func 关键字,类似python中的def 关键字。表示定义一个函数,函数名必须叫main
func main() {
fmt.Println("hello world")
}
// 命令行两种执行方式:
// 命令行编译后执行生成的编译文件即可 go build test.go --> test.exe
// 命令行直接运行 .go 的文件 go run test.go (相当于对编译和执行命令的封装)
二、变量相关
- go中,变量不能重复声明,但是可以重新赋值,同一个变量名在不同作用域中可以重复声明
2. 标识符和关键字
-
标识符就是python中的变量名, 由字母数字和
_
(下划线)组成,并且只能以字母和_
开头 。 -
关键字就是有各种特定作用的名字。如python中的
if def return
等等。go语言里有25个关键字,并且还有37个保留字。我们不建议用关键字或保留字当做变量名即标识符。
3. 变量声明
- 类似前端JavaScript的变量声明方式
(1)普通声明
i. 不赋值声明
// 语法1: var 变量名 变量类型 = 变量值
// 行尾无需分号
// 例如:
var name string
var age int
var isOk bool
// 语法2:批量声明
var (
a string
b int
c bool
d float32
)
// 语法3:批量声明
package main
import "fmt"
func main() {
var width, height int
fmt.Println("width is", width, "height is", height)
width = 100
height = 50
fmt.Println("new width is", width, "new height is ", height)
}
// 打印结果:
width is 0 height is 0
new width is 100 new height is 50
-
已经声明的变量若未对其进行初始化,他们都会有一个默认值
- 数字类型是
0
,字符串是空字符串, 布尔型变量默认为false
。 切片、map、指针、接口、channel 只声明,未初始化值时都默认为nil
,某些函数返回error时,无报错时的error恒等于nil
- 数字类型是
ii. 赋值声明
// 语法:
var 变量名 类型 = 变量值
// 例子:
var name string = "test_name"
var age int = 18
// 一次初始化多个变量:
var name string, age int = "test_name", 20
(2)不指定类型声明
-
如果变量有初始值,那么 Go 能够自动推断具有初始值的变量的类型。因此,如果变量有初始值,就可以在变量声明中省略
类型
var name = "test_name" var age = 18 // 一次初始化多个变量: var name, age = "test_name", 20
(3)简短声明
-
在函数内部,可以使用更简略的
:=
方式声明并初始化变量 -
简短声明要求 := 操作符左边的所有变量都有初始值,否则执行会报错
-
简短声明的语法要求 := 操作符的左边至少有一个变量是尚未声明的,否则执行会报错
-
简短声明看似可以重新定义之前定义过的变量,实际上简短声明只是对之前定义的变量进行改值
// 语法: 变量名 := 变量值 package main import "fmt" // 全局变量m var m = 100 func main() { n := 10 m := 200 // 此处声明局部变量m fmt.Println(m, n) } // 运行中进行赋值 package main import ( "fmt" "math" ) func main() { a, b := 145.8, 543.8 c := math.Min(a, b) fmt.Println("minimum value is ", c) } // 简单声明时包含之前声明过的变量 package main import "fmt" func main() { a, b := 20, 30 // 声明变量a和b fmt.Println("a is", a, "b is", b) b, c := 40, 50 // b已经声明,但c尚未声明 fmt.Println("b is", b, "c is", c) b, c = 80, 90 // 给已经声明的变量b和c赋新值 fmt.Println("changed b is", b, "c is", c) }
4. 匿名变量(空白符)
-
类似python中的解压缩时,用
_
代替不需要的值。 匿名变量用一个下划线_
表示,用来接收舍弃的值,且无法调用_
func foo() (int, string) { return 10, "test_name"; } func main() { x, _ := foo() _, y := foo() fmt.Println("x_val", x) fmt.Println("y_val", y) }
-
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在
Lua
等编程语言里,匿名变量也被叫做哑元变量。
5. 注意小结
-
函数外的每个语句都必须以关键字开始(var、const、func等)
-
**
:=
不能使用在函数外 **
_
多用于占位,表示忽略值,无法使用
三、常量
-
什么是常量
-
常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值
-
声明常量只是把
var
换成了const
,**常量在定义的时候必须赋值,且常量的值在编译的时候就是确定下来的,因此 等号 右侧不能出现需要计算的表达式 **
1.普通声明常量方式:
const pi = 3.1415
const e = 2.7182
2.批量声明不同值的常量方式:
const (
pi = 3.1415
e = 2.7182
)
3.批量声明同一值的常量:const同时声明多个常量时,如果省略了值则表示和上面一行的值相同
const (
n1 = 100
n2
n3
)
4. 定义需要计算的常量会报错
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Hello, playground")
var a = math.Sqrt(4) // 允许
const b = math.Sqrt(4) // 不允许
}
// 常量的值会在编译的时候确定。因为函数调用发生在运行时,所以不能将函数的返回值赋值给常量
5. 数字常量的运用,只有数字常量可以这样赋值,字符串常量、布尔常量都不行(见5.1 5.2 示例)
package main
import (
"fmt"
)
func main() {
const a = 5
var intVar int = a
var int32Var int32 = a
var float64Var float64 = a
var complex64Var complex64 = a
fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}
// 打印结果
intVar 5
int32Var 5
float64Var 5
complex64Var (5+0i)
5.1 字符串常量
package main
func main() {
var defaultName = "Sam" // 允许
type myString string // 定义一个我们自己的类型mystring,本质用法和string是一样的
var customName myString = "Sam" // 允许
customName = defaultName // 不允许
}
5.2 布尔常量
package main
func main() {
const trueConst = true
type myBool bool // 定义一个我们自己的类型myBool,本质用法和bool是一样的
var defaultBool = trueConst // 允许
var customBool myBool = trueConst // 允许
defaultBool = customBool // 不允许
}
四、iota(暂时了解)
-
什么是
iota
iota
是go语言的常量计数器,只能在常量的表达式中使用iota
在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota
计数一次iota
**可理解为const语句块中的行索引 **
-
5种实例:
1. 普通例子 const ( n1 = iota //0 n2 //1 n3 //2 n4 //3 ) 2. 使用_跳过某些值 const ( n1 = iota //0 n2 //1 _ n4 //3 ) 3.iota声明中间插队 const ( n1 = iota //0 n2 = 100 //1 n3 = iota //2 n4 //3 ) const n5 = iota //0 4. 定义数量级 // 这里的<<表示左移操作,1<<10表示将1的二进制表示向左移10位,也就是由1变成了10000000000,也就是十进制的1024。同理2<<2表示将2的二进制表示向左移2位,也就是由10变成了1000,也就是十进制的8 const ( _ = iota KB = 1 << (10 * iota) MB = 1 << (10 * iota) GB = 1 << (10 * iota) TB = 1 << (10 * iota) PB = 1 << (10 * iota) ) 5. 多个iota定义在一行 const ( a, b = iota + 1, iota + 2 //1,2 c, d //2,3 e, f //3,4 )