Go语言基础语法
特点
- 高性能,高并发
- 语法简单
- 丰富的标准库
- 完整的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
基础语法-Hello World
//入口包的一部分
package main
// 导入标准库的fmt包,屏幕输入输出字符串格式化字符串
import {
"fmt"
}
// 主函数
func main(){
fmt.Println("Hello World")
}
基础语法-变量
- 变量类型: int,float64,string,bool
- 字符串可用加号拼接,可用==比较
- 声明变量: var name = value,var name type = value,name:=value
- 常量: const name = value,无确定类型
基础语法-if else
if condition { }条件无需括号,if后必须有大括号
基础语法-循环
- 只有for循环,无括号,可以使用break,continue
基础语法-switch
- 变量名不需要类型,switch后无需括号,case后无需break
- 可以使用任意变量类型
- 可以取代if else语句,switch后不加变量,在case后写条件语句,可以多个
func main() {
a:= 1
switch a{
case 1:
fmt.Println("1")
case 2:
fmt.Println("2")
default:
fmt.Println("default")
}
t:= time.Now()
switch {
case t.Hour() < 12:
fmt.Println("before noon")
default: fmt.Println("after noon")
}
}
切片
- 可变长度的数组
- 创建切片:
s:= make([]int,5) - 添加元素:
s= append(s,1) - 拷贝数据:
copy(s1,s2) - 切片操作:
s[start:end]
func main() {
s:= make([]int,3)
s[0] = 1
s[1] = 2
s[2] = 3
s=append(s,4)
s2:= make([]int,len(s))
copy(s2,s)
fmt.Println(s2[1:3])
}
map
- 类似java的hashmap,无序
- 创建map:
m:= make(map[string]int) - 添加元素:
m["key"]=1 - 读取:
m["key"] - 判断是否存在:
v,ok := m["key"] - 删除:
delete(m,"key")
func main() {
m:= make(map[string]int)
m["a"]=1
m["b"]=2
v,ok := m["a"]
fmt.Println(v,ok)
delete(m,"a")
m2:= map[string]int{"a":1,"b":2}
fmt.Println(m2)
}
range
- 可以用来遍历map和slice,类似java的foreach
- 对于数组可返回下标和值
- 对于map可返回key和value
func main() {
nums := []int{1,2,3}
sum := 0
m:= map[string]int{"a":1,"b":2}
for i,num:= range nums {
sum += num
}
fmt.Println(sum)
for k,v:= range m {
fmt.Println(k,v)
}
for k:= range m {
fmt.Println(k)
}
}
函数
- 返回变量类型后置
func add(a,b int) int - 可以返回多个值
func add(a,b int) (int,int)
指针
- 对传入的参数进行修改,需要使用指针
func add(a,b *int) - 调用时需使用
&
func add(*a int) int {
return *a+2
}
func main() {
a:=1
fmt.Println(add(&a))
}
结构体
- 带类型的字段的集合
- 初始化:使用结构体名称,对每个字段进行初始化,也可以部分
- 使用
.访问字段 - 可作为参数传递,分为指针和非指针
结构体方法
- 类似java中的类成员方法
- 结构体可使用
.访问该方法 - 定义方法:
func (s *Student) Print(age int) {}可以有带指针不带指针两种
type Student struct {
name string
age int
}
func (s *Student) Print(age int) {
u.age+1
}
func main() {
s:=Student{"zhangsan",18}
fmt.Println(s.age)
}
错误处理
- 在函数的返回值类型后添加
error,表示该函数可能会返回错误,需要return errorerrors.New("错误信息") - 调用时需要用
err:=接收返回值,需要判断错误,没有错误时才可以取真正的返回值
type Student struct {
name string
age int
}
func find(Students []Student,name string)(s *Student,err error){
for _,v:=range Students{
if v.name==name{
return &v,nil
}
}
return nil,errors.New("没有找到该学生")
}
func main(){
var students = []Student{
{"张三",18},
{"李四",19},
}
s,err:=find(students,"张三")
if err!=nil{
fmt.Println(err)
return
}
fmt.Println(s.name,s.age)
}
字符串操作
- strings包中有很多对字符串进行操作的方法,比如:
- 字符串中是否包含某个子字符串:
strings.Contains(str,substr) - 对某个子串计数
strings.Count(str,substr) - 判断str是否以prefix开头
strings.HasPrefix(str,prefix) - 判断str是否以suffix结尾
strings.HasSuffix(str,suffix) - 返回substr在str中第一次出现的位置,如果没有返回-1:
strings.Index(str,substr) - 将strs中的元素用sep拼接成一个字符串:
strings.Join(strs,sep) strings.LastIndex(str,substr)- 重复str count次:
strings.Repeat(str,count) - 替换str中old为new,count为替换的次数:
strings.Replace(str,old,new,count) - 将str按sep分割成字符串数组:
strings.Split(str,sep) strings.ToLower(str)strings.ToUpper(str)- len(str),一个中文可能对应多个字符
字符串格式化
- fmt包中有多个格式化方法,如:
- 打印并换行
fmt.Println(str) - %v可以打印任意类型的变量
fmt.Printf("%v",str) - 对于结构体%+v 可以打印结构体的所有字段和值,%#v打印出结构体类型名称和字段
- 打印保留小数点后两位
fmt.Printf("%.2f",float64)
JSON处理
- 结构体每个字段需要大写开头,否则无法被json解析
- json包中有两个方法:
- Marshal将结构体序列化成json字符串:
json.Marshal(obj) - Unmarshal将json字符串反序列化成结构体:
json.Unmarshal([]byte(str),obj)
- Marshal将结构体序列化成json字符串:
type User struct {
Name string
Age int `json:"age"`
}
func main() {
user := User{"张三", 18}
jsonStr,err := json.Marshal(user)
if err != nil {
panic(err)// 处理错误
}
fmt.Println(string(jsonStr))//需要转换为字符串
var user2 User
err=json.Unmarshal(jsonStr,&user2)// 需要传入指针
if err != nil {
panic(err)
}
fmt.Println(user2)// {张三 18}
}
时间处理
- 获取当前时间
time.Now() - 创建一个时间:
time.Date(year,month,day,hour,min,sec,nsec,loc) - 将一个时间格式化成字符串:
time.Format("2006-01-02 15:04:05") - 得到一个时间段:
t.Sub(t2)并且获取时间段有多少分钟多少秒 - 获取时间戳:
time.Unix()
func main() {
now := time.Now()
fmt.Println(now)
// 创建一个时间
t:= time.Date(2020, 12, 12, 12, 12, 12, 12, time.Local)
fmt.Println(t.Format("2006-01-02 15:04:05"))// 格式化
diff:= now.Sub(t)// 时间段
fmt.Println(diff.Minutes())
fmt.Println(time.Unix())// 时间戳
}
数字解析
- 在strconv包中有ParseInt、ParseFloat,Atoi等方法
func main() {
a, _ := strconv.ParseInt("123", 10, 64)// 10进制
b, _ := strconv.ParseFloat("123.45", 64)// 浮点数
c, _ := strconv.Atoi("123")// 字符串转数字
fmt.Println(a, b, c)
}
进程信息
func main() {
//go run main.go a b c d
fmt.Println(os.args)//["main.go", "a", "b", "c", "d"]
fmt.Println(os.Getenv("PATH"))//获取环境变量
fmt.Println(os.Setenv("PATH", "new path"))//设置环境变量
//启动子进程
buf,err:= exec.Command("grep","127.0.0.1","/etc/hosts").CombinedOutput()
if err!=nil{
panic(err)
}
fmt.Println(string(buf))//输出子进程执行结果
}