- 文件开头:
package ……,表示这是……包的一部分 - 用
var <name> <type//若无需强调类型,可省略,将自动适配> = <value>或者<name> := <value>来声明变量 - Go语言字符串是内置类型,可以通过 + 号拼接、= 号比较等
- 用
const <name> <type>=<value>来声明常量,常量无确定类型,根据使用的上下文自动确定类型 - Go语言if后面没有括号,if的条件后面只能有大括号,执行语句要写在下一行
- Go语言只有**
for循环** - Go语言
switch case:变量不加括号,可以为任意类型,甚至可以代替if-else、默认在每个case里面都有个break,无需自己编写 - 数组
var <name> [len]<type>{…,…,…} - 切片: 相比数组来说长度不固定
- 用
make( [ ]<type>,<len>)来创建切片 - 用
append(<name>,<value>)来添加元素,用append添加元素要赋值给切片如:
s=append(s, "hello") - 用
copy(<name>,<name>)来拷贝切片,如下:
c,s为两个不同的切片copy(c, s) - 有如python一样的切片操作,如下
s:= make([ ]string, 5)
s[0]=a
s[1]=b
s[2]=c
s[3]=d
s[4]=e
s[5]=f
fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5]) //[a b c d f]
fmt.Println(s[:2]) //[c d e f]
10. Map//在别的语言里可能会叫字典或者哈希
- 用
make(map[<keytype>]<valuetype>)来创建MAP,如
m := make(map[string] int) - 用
<name>[<key>] = <value>为map添加元素,如下
m["one"]=1
m["two"]=2 - 还有以下操作
fmt.Println(m) //map[one:1 two:2]
fmt.Println(len(m)) //2
fmt.Println(m["one"]) //1
fmt.Println(m["unknow"]) //0
- 用
delete(<name>, <value>)来删除 k , v 对 - 用ok字段判断是否有该 k , v 对,如下
r, ok:=m["unknow"]
fmt.Println(r, ok) //0 false
- 用Range来遍历数组、切片、Map
- 遍历数组,会返回两个值一个是索引(下标),另一个是数组的值:
//假设nums := [ ]int {2,3,4},sum := 0
for i, num := range nums {//这里可以使用_将index省略
sum += num
if num == 2 {
fmt.Println("index:", i,"num:" , num) // index:0 num:2
}
}
fmt.Println(sum) //9
- 遍历切片:
m:=map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
for k := range m {
fmt.Println("key", k) // key a; key b
}
- 函数
Go语言中,变量是后置的,在大多数业务代码总中,函数总是返回多个值,第一个是真实值,第二个一般为错误信息例如:
func add(a int, b int) int {
return a + b
}
func exists (m map[string]string, k string)(v string, ok bool) {//像这里,当该值不存在时,将返回false,false即为错误信息
v, ok = m [k]
return v, ok
}
- 指针
Go语言的指针用法与C\C++类似,但用法没那么多和复杂,主要用于修改常用变量的值 - 结构体
结构体是带类型的字段的集合
type user struct{ //结构体的定义
name string
password string
}
func main() {
a := user {name :"wang", password :"1024"}
b := user {"wang" , "1024"}
c := user {name: "wang"}//当带变量名输入值时,可以输入特定字段的值,未初始化的字段为空值,即int类型为0,string类型为空字符串
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
fmt.Println(a,b,c,d) // {wang 1024} {wang 1024} {wang 1024} {wang1024}
fmt.Println(checkPassword(a,"haha")) //false
fmt.Println(checkPassword2(&a,"haha")) //false
}
func checkPassword (u user, password string) bool {//结构体可作为函数的参数传递
return u.password == password
}
func checkPassword2 (u *user, password string) bool {//当使用指针进行传输字符串时,可避免拷贝超大结构体所带来的资源损失
return u.password == password
}
- Go语言中,可以为结构体定义结构体方法,结构体方法类似于其他语言的类成员函数,例如:
func (u user) checkPassword (password string) bool {//与JAVA类似,新声明了一个结构体后,Go可以使用“.",对结构体方法进行调用
Return u.password == password
}
func (u *user) resetPassword (password string) { //结构体方法也可以使用指针传参
u.password = password
}
func main(){
a := user {name: "wang", password: "1024" }
a.resetPassword ("2048")
fmt.Println(a.checkPassword("2048"))
}
- 错误处理
Go语言中通常通过在函数中返回信息来进行错误的处理(不同于Java的异常,可以知道是哪个函数返回了错误信息)
func findUser (users[] user, name string)(v *user, err error){//这里有个error类型,表示这个函数可能会发生错误
for _, u := range users {
if u.name == name {
return &u, nil
}
}
Return nil, errors.New("notfound") //这里New了一个error,error的信息为notfound
}
func main(){
u, err := findUser([]user{{"wang", "1024"}},"wang")
if err != nil { //error的处理
fmt.Println(err)
return
}
}
- 字符串处理
使用Stings包,有以下处理字符串的功能
| 语句 | 结果 | 作用 |
|---|---|---|
a:="hello" | ||
fmt.Println(strings.Contains(a,"ll")) | TRUE | 是否包含 |
fmt.Println(strings.Count(a,"l")) | 2 | 字符计数 |
fmt.Println(strings.HasPrefix(a,"he")) | TRUE | 是否以…开头 |
fmt.Println(strings.HasSuffix(a,"llo")) | TRUE | 是否以…结尾 |
fmt.Println(strings.Index(a,"ll")) | 2 | 查找某个字符串的位置 |
fmt.Println(strings.Join([]string{"he","llo"},"-")) | he-llo | 在字符串中间插入 |
fmt.Println(strings.Repeat(a,2)) | hellohello | 重复输出字符串 |
fmt.Println(strings.Replace(a,"e","E",-1)) | hEllo | 替换 |
fmt.Println(strings.Split("a-b-c","-")) | [a b c] | 使用符号分离字符串中的字符 |
fmt.Println(strings.ToLower(a)) | hello | 使字符串全为小写 |
fmt.Println(strings.ToUpper(a)) | HELLO | 使字符串全为大写 |
fmt.Println(len(a)) | 5 | 输出字符串长度 |
b := "你好" | ||
fmt.Println(len(b)) | 6 | 中文字符串可能占据不同的字符串长度 |
- 字符串格式化
type point struct{
x, y int
}
s := "hello"
n := 123
p := point{1,2}
fmt.Println(s,n)//hello123,println是打印并换行
fmt.Println(p)//{12}
fmt.Printf("s=%v\n",s)//s=hello,可以使用%v来打印任意类型的变量
fmt.Printf("n=%v\n",n)//n=123
fmt.Printf("p=%v\n",p)//p={12}
fmt.Printf("p=%+v\n",p)//p={x:1y:2},%+v可以输出更详细的信息,如字段名称和值
fmt.Printf("p=%#v\n",p)//p=main.point{x:1,y:2},%#v可以进一步输出更详细的信息
f := 3.141592653
fmt.Println(f)//3.141592653
fmt.Printf("%.2f\n",f)//3.14,打印特定格式的浮点数
- JSON操作
使用encoding/json包对Json进行操作
type userInfo struct{ //需要保证结构体的每个字段的开头字母为大写,即为Go中的公开字段
Name string
Age int `json:"age"` //'json: "age"这个tag将Age字段的输出变成了小写,可以以此类推修改
Hobby[] string
}
func main() {
a=userInfo{Name:"wang",Age:18,Hobby:[string{"Golang","TypeScript"}}
buf,err:=json.Marshal(a)//这样,在Go中就可以直接使用json.Marshal(<name>)将JSON序列化成一个Bytes数组,这里即buf时一个bytes数组
if err != nil {
panic(err)
}
fmt.Println(buf)//[123 34 7897...],这里是一些16进制的编码
fmt.Println(string(buf))//{"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]},这里使用了强制类型转换将buf转换为string类型数组
buf, err = json.MarshalIndent(a,"","\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal(buf,&b)//这里使用了json.Unmarshal(<src_name>, &<dest_name>)反序列化到一个空的变量中
if err != nil {
panic(err)
}
fmt.Printf("%#v\n",b)//main.userInfo{Name:"wang",Age:18,Hobby:[]string{"Golang","TypeScript"}}
}
- 时间处理:time包
func main() {
now := time.Now() //获取当前时间
fmt.Println(now)
t := time.Date(2022,3,27,1,25,36,0,time.UTC)
t2 := time.Date(2022,3,27,2,30,36,0,time.UTC)
fmt.Println(t)//2022-03-2701:25:36+0000UTC
fmt.Println(t.Year(),t.Month(),t.Day(),t.Hour(),t.Minute())//2022march27125
fmt.Println(t.Format("2006-01-0215:04:05"))//2022-03-2701:25:36,格式化时间,"2006-01-0215:04:05"是Go中固定的时间格式,而不同于其他语言中使用的yymmdd……
diff := t2.Sub(t)//两个时间相减
fmt.Println(diff)//1h5m0s
fmt.Println(diff.Minutes(),diff.Seconds())//65 3900,这里分别对应了上面时间段分别对应多少分钟,多少秒
t3,err := time.Parse("2006-01-0215:04:05","2022-03-2701:25:36")
if err != nil {
panic(err)
}
fmt.Println(t3 == t)//true
fmt.Println(now.Unix())//1648738080,这里获取了一个时间戳
}
- 字符串转数字:strconv包
func main(){
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234
n, _ := strconv.ParseInt("111", 10, 64)//第一个参数是字符串,第二个是进制(如果是0就为自动),第三个是精度
fmt.Println(n) // 111
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) // 4096
n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid
syntax
}
- 环境:os 和 os/exec 包
func main() {
// go run example/20-env/main.go a b c d
fmt.Println(os.Args)//[/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d],os.Args获取的是Go文件执行时命令行的一些参数
fmt.Println(os.Getenv("PATH"))// /usr/local/go/bin...,os.Getenv("PATH")获取了环境变量的路径
fmt.Println(os.Setenv("AA", "BB"))//os.Setenv( )写入环境变量
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()//exec.Command( ),快速启动子进程,并获取其输入输出
if err != nil {
panic(err)
}
fmt.Println(string(buf)) // 127.0.0.1 localhost
}