Go语言概念、基本数据类型、常量变量和运算符
目录
- go快速入门
- go基本概念
- 基本数据类型
- 常量变量运算符
go快速入门
Go语言简介
Go语言,通常称为Golang,是由Google设计的一种静态类型、编译型的编程语言。它旨在提高开发者的生产力,简化并加速软件开发流程。Go语言具有以下特点:
- 简洁性:Go语言语法简单,易于学习,没有类如C++中的模板或Java中的泛型这样的复杂特性。
- 并发支持:Go语言内置了对并发的支持,通过goroutines和channels来实现。
- 标准库:Go拥有一个强大的标准库,提供了大量的工具和库来帮助开发者快速构建应用。
- 编译速度快:Go语言的编译速度非常快,接近于C语言。
- 跨平台:Go语言可以编译成各种不同的平台,包括Windows、Linux、macOS等。
Go语言快速入门
开发环境搭建
- 安装Go: 下载并安装最新版本的Go语言环境。
- 设置环境变量: 设置GOROOT为Go的安装路径,并将GOPATH(Go 1.11之前版本)或GO111MODULE(模块化支持)设置好。
- 安装编辑器或IDE: 可以选择Visual Studio Code, IntelliJ IDEA, 或者GoLand等。
第一个Go程序 创建一个新的目录作为工作区,并在其中编写第一个Go程序:
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
保存文件为hello.go
,然后在命令行中运行:
go run hello.go
项目结构 一个典型的Go项目结构可能如下所示:
myproject/
├── cmd/
│ └── myapp/
│ ├── main.go
│ └── ...
├── internal/
│ ├── pkg1/
│ │ ├── pkg1.go
│ │ └── ...
│ └── pkg2/
│ ├── pkg2.go
│ └── ...
├── pkg/
│ ├── pkg3/
│ │ ├── pkg3.go
│ │ └── ...
│ └── pkg4/
│ ├── pkg4.go
│ └── ...
├── go.mod
└── go.sum
cmd/
: 包含应用程序入口点,每个子目录代表一个可执行命令。internal/
: 存放内部包,这些包只能被项目内的其他包访问。pkg/
: 存放外部可以依赖的包。go.mod
: Go模块元数据文件,用于管理依赖关系。go.sum
: 文件包含直接和间接依赖的校验和,确保依赖的一致性和安全性。
构建与测试 你可以通过以下命令来构建你的Go应用:
go build -o myapp ./cmd/myapp
对于测试,Go的标准库提供了一个简单的测试框架,可以通过下面的命令来运行测试:
go test ./...
go基本概念
Go语言的主要特征:
- 自动立即回收。
- 更丰富的内置类型。
- 函数多返回值。
- 错误处理。
- 匿名函数和闭包。
- 类型和接口。
- 并发编程。
- 反射。
- 语言交互性。
Go语言命名:
-
Go的函数、变量、常量、自定义类型、包(package)的命名方式遵循以下规则:
- 首字符可以是任意的Unicode字符或者下划线
- 剩余字符可以是Unicode字符、下划线、数字
- 字符长度不限
-
Go只有25个关键字 break、default、func、interface、select、case、defer、go、map、struct、chan、else、goto、package、switch、const、fallthrough、if 、range、ype、continue、for、import、return、var
-
Go还有37个保留字
Constants: true false iota nil
Types: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex128 complex64 bool byte rune string errorFunctions: make len cap new append copy close delete complex real imag panic recover
-
可见性:
- 声明在函数内部,是函数的本地值,类似private
- 声明在函数外部,是对当前包可见(包内所有.go文件都可见)的全局值,类似protect
- 声明在函数外部且首字母大写是所有包可见的全局值,类似public
Go语言声明:
-
有四种主要声明方式:
var(声明变量), const(声明常量), type(声明类型) ,func(声明函数)。
Go 值类型:
bool
int(32 or 64), int8, int16, int32, int64
uint(32 or 64), uint8(byte), uint16, uint32, uint64
float32, float64
string
complex64, complex128
array // 固定长度的数组
Go 引用类型:(指针类型)
- slice -- 序列数组(最常用)
- map -- 映射
- chan -- 管道
Go 内置函数
- append -- 用来追加元素到数组、slice中,返回修改后的数组、slice
- close -- 主要用来关闭channel
- delete -- 从map中删除key对应的value
- panic -- 停止常规的goroutine (panic和recover:用来做错误处理)
- recover -- 允许程序定义goroutine的panic动作
- real -- 返回complex的实部 (complex、real imag:用于创建和操作复数)
- imag -- 返回complex的虚部
- make -- 用来分配内存,返回Type本身(只能应用于slice, map, channel)
- new -- 用来分配内存,主要用来分配值类型,比如int、struct。返回指向Type的指针
- cap -- capacity是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)
- copy -- 用于复制和连接slice,返回复制的数目
- len -- 来求长度,比如string、array、slice、map、channel ,返回长度
- print、println -- 底层打印函数,在部署环境中建议使用 fmt 包
init 函数
go语言中init函数用于包(package)的初始化,该函数是go语言的一个重要特性。
- init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
- 每个包可以拥有多个init函数
- 包的每个源文件也可以拥有多个init函数
- 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
- 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
- init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
init 函数和 main 函数的异同
相同点:
- 两个函数在定义时不能有任何的参数和返回值,且Go程序自动调用。
不同点:
- init可以应用于任意包中,且可以重复定义多个。
- main函数只能用于main包中,且只能定义一个。
两个函数的执行顺序:
-
对同一个go文件的init()调用顺序是从上到下的。
-
对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()函数。
-
对于不同的package,如果不相互依赖的话,按照main包中”先import的后调用”的顺序调用其包中的init(),如果package存在依赖,则先调用最早被依赖的package中的init(),最后调用main函数。
go命令
- go env用于打印Go语言的环境信息。
- go run命令可以编译并运行命令源码文件。
- go get可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并对它们进行编译和安装。
- go build命令用于编译我们指定的源码文件或代码包以及它们的依赖包。
- go install用于编译并安装指定的代码包及它们的依赖包。
- go clean命令会删除掉执行其它命令时产生的一些文件和目录。
- go doc命令可以打印附于Go语言程序实体上的文档。我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的。
- go test命令用于对Go语言编写的程序进行测试。
- go list命令的作用是列出指定的代码包的信息。
- go fix会把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码。
- go vet是一个用于检查Go语言源码中静态错误的简单工具。
- go tool pprof命令来交互式的访问概要文件的内容。
基本类型
整型
整型分为以下两个大类: 按长度分为:int8
、int16
、int32
、int64
对应的无符号整型:uint8
、uint16
、uint32
、uint64
其中,uint8
就是我们熟知的byte
型,int16
对应C语言中的short
型,int64
对应C语言中的long
型。
浮点型
Go语言支持两种浮点型数:float32
和float64
。这两种浮点型数据格式遵循IEEE 754
标准: float32
的浮点数的最大范围约为3.4e38
,可以使用常量定义:math.MaxFloat32
。 float64
的浮点数的最大范围约为 1.8e308
,可以使用一个常量定义:math.MaxFloat64
。
复数
complex64
和complex128
复数有实部和虚部,complex64
的实部和虚部为32位,complex128
的实部和虚部为64位。
布尔值
Go语言中以bool类型进行声明布尔型数据,布尔型数据只有true
(真)和false
(假)两个值。
字符串
Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int
、bool
、float32
、float64
等)一样。 Go 语言里的字符串的内部实现使用UTF-8
编码。 字符串的值为双引号(“)中的内容,可以在Go语言的源码中直接添加非ASCII码字符,
字符串转义符
- \r 回车符(返回行首)
- \n 换行符(直接跳到下一行的同列位置)
- \t 制表符
- ' 单引号
- " 双引号
- \ 反斜杠
多行字符串
Go语言中要定义一个多行字符串时,就必须使用反引号字符:
s1 := `第一行
第二行
第三行
`
fmt.Println(s1)
字符串的常用操作
- len(str) 求长度
- +或fmt.Sprintf 拼接字符串
- strings.Split 分割
- strings.Contains 判断是否包含
- strings.HasPrefix,strings.HasSuffix 前缀/后缀判断
- strings.Index(),strings.LastIndex() 子串出现的位置
- strings.Join(a[]string, sep string) join操作
byte和rune类型
Go 语言的字符有以下两种:
- uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
- rune类型,代表一个 UTF-8字符。
当需要处理中文、日文或者其他复合字符时,则需要用到rune
类型。rune
类型实际是一个int32
。 Go 使用了特殊的 rune
类型来处理 Unicode
,让基于 Unicode
的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾
// 遍历字符串
func traversalString() {
s := "pprof.cn博客"
for i := 0; i < len(s); i++ { //byte
fmt.Printf("%v(%c) ", s[i], s[i])
}
fmt.Println()
for _, r := range s { //rune
fmt.Printf("%v(%c) ", r, r)
}
fmt.Println()
}
修改字符串
要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
func changeString() {
s1 := "hello"
// 强制类型转换
byteS1 := []byte(s1)
byteS1[0] = 'H'
fmt.Println(string(byteS1))
s2 := "博客"
runeS2 := []rune(s2)
runeS2[0] = '狗'
fmt.Println(string(runeS2))
}
类型转换
强制类型转换的基本语法如下:T(表达式)其中,T表示要转换的类型。表达式包括变量、复杂算子和函数返回值等.
func sqrtDemo() {
var a, b = 3, 4
var c int
// math.Sqrt()接收的参数是float64类型,需要强制转换
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)
}
常量变量运算符
常量
相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。
const pi = 3.1415
const e = 2.7182
// 多个常量也可以一起声明
const (
pi = 3.1415
e = 2.7182
)
const (
n1 = 100
n2
n3
)
// iota是go语言的常量计数器,只能在常量的表达式中使用。iota在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。
const (
n1 = iota //0
n2 //1
_
n4 //3
)
const (
n1 = iota //0
n2 = 100 //100
n3 = iota //2
n4 //3
)
变量
var 变量名 变量类型; var 变量名 类型 = 表达式
var name string
var age int
var isOk bool
var name string = "pprof.cn"
var sex int = 1
var name, sex = "pprof.cn", 1
func main() {
n := 10
m := 200 // 此处声明局部变量m
fmt.Println(m, n)
x, _ := foo()
_, y := foo() // 匿名变量
}
func foo() (int, string) {
return 10, "Q1mi"
}
运算符
算数运算符
+
相加-
相减*
相乘/
相除%
求余
关系运算符
==
检查两个值是否相等,如果相等返回 True 否则返回 False。!=
检查两个值是否不相等,如果不相等返回 True 否则返回 False。>
检查左边值是否大于右边值,如果是返回 True 否则返回 False。>=
检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。<
检查左边值是否小于右边值,如果是返回 True 否则返回 False。<=
检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。
逻辑运算符
&&
逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。ll
逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。!
逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。
位运算符
&
参与运算的两数各对应的二进位相与。(两位均为1才为1)l
参与运算的两数各对应的二进位相或。(两位有一个为1就为1)^
参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(两位不一样则为1)<<
左移n位就是乘以2的n次方。>>
右移n位就是除以2的n次方。“a>>b”是把a的各二进位全部右移b位。
赋值运算符
=
简单的赋值运算符,将一个表达式的值赋给一个左值+=
相加后再赋值-=
相减后再赋值*=
相乘后再赋值/=
相除后再赋值%=
求余后再赋值<<=
左移后赋值>>=
右移后赋值&=
按位与后赋值l=
按位或后赋值^=
按位异或后赋值
版权声明
本文仅代表作者观点,不代表区块链技术网立场。
本文系作者授权本站发表,未经许可,不得转载。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。