go语言的基础语法
1、hello world
- 编程语言的开始是hello world
- 通过输出hello world了解go语言的最基础语法
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
2、数据类型
- 基础数据类型类似于js的语法
- 定义数据类型的关键字
var
- 使用
TypeOf函数查看数据类型
package main
import (
"fmt"
"reflect"
)
func main() {
var a = "initial"
fmt.Println(reflect.TypeOf(a))
var b, c int = 1, 2
fmt.Println(reflect.TypeOf(b))
var d = true
fmt.Println(reflect.TypeOf(d))
var e float64
fmt.Println(reflect.TypeOf(e))
f := float32(e)
fmt.Println(reflect.TypeOf(f))
g := a + "foo"
fmt.Println(reflect.TypeOf(g))
}
3、循环语句
- go语言中循环只有for
- 省去了while,可以使用for代替
- 同时for循环的语法比Java,C,C++更简洁
package main
import "fmt"
func main() {
i := 1
for {
fmt.Println("loop")
break
}
for j := 7; j < 9; j++ {
fmt.Println(j)
}
for n := 0; n < 5; n++ {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
}
4、选择语句
- if else判断语句
- Switch case 语句
- if语句与上面for循环语句类似,省去了括号更加简洁
- Switch case 语句更加灵活,可以在case中进行运算比较
package main
import(
"fmt"
"time"
)
func main() {
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
if 8%4 == 0 {
fmt.Println("8 is divisible by 4")
}
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
a := 2
switch a {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
case 4, 5:
fmt.Println("four or five")
default:
fmt.Println("other")
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
}
5、数组
package main
import "fmt"
func main() {
var a [5]int
a[4] = 100
fmt.Println("get:", a[2])
fmt.Println("len:", len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println(b)
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
}
6、切片
- 切片是一个可变长的数组
- 类似于java当中的list的集合
- 使用mark函数进行创建
import "fmt"
func main() {
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])
fmt.Println("len:", len(s))
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s)
c := make([]string, len(s))
copy(c, s)
fmt.Println(c)
fmt.Println(s[2:5])
fmt.Println(s[:5])
fmt.Println(s[2:])
good := []string{"g", "o", "o", "d"}
fmt.Println(good)
}
7、字典
- go语言中的字典与java中的map类型一致,叫法不同而已
- 字典的叫法在python当中是一致的
package main
import "fmt"
func main() {
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m)
fmt.Println(len(m))
fmt.Println(m["one"])
fmt.Println(m["unknow"])
r, ok := m["unknow"]
fmt.Println(r, ok)
delete(m, "one")
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)
}
8、range
- 遍历数组,字典等相关的数据结构类型
- range可以返回数据结构对应的下标,值,键等属性
- range遍历数组返回下标以及对应的值
- range遍历字典返回键和值也可以进行单个返回
- 当只要值无需键的时候,要在前面加
_作为占位符
- 当只要键的时候则无需占位符
package main
import "fmt"
func main() {
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num)
}
}
fmt.Println(sum)
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v)
}
for k := range m {
fmt.Println("key", k)
}
}
9、函数
- 函数的基础语法有返回值,函数名,参数
- go语言中的函数可以返回多个值,一般是将值以及错误信息一起进行返回
package main
import "fmt"
func add(a int, b int) int {
return a + b
}
func add2(a, b int) int {
return a + b
}
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
func main() {
res := add(1, 2)
res = add2(2, 3)
fmt.Println(res)
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok)
}
10、指针
- 指针可以方便传参的时候对数据本身进行操作,而不是对其的一个拷贝进行操作
- 使用指针的时候要使用
&进行取地址
package main
import "fmt"
func add2(n int) {
n += 2
}
func add2ptr(n *int) {
*n += 2
}
func main() {
n := 5
add2(n)
fmt.Println(n)
add2ptr(&n)
fmt.Println(n)
}
11、结构体
- go语言的结构体与c语言不同,go语言可以支持结构体方法,可以对结构体当中的属性进行操作
- 类似于面向对象语言当中的类,类当中可以有属性,方法等操作
package main
import "fmt"
type user struct {
name string
password string
}
func main() {
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}
c := user{name: "wang"}
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
fmt.Println(a, b, c, d)
fmt.Println(checkPassword(a, "haha"))
fmt.Println(checkPassword2(&a, "haha"))
}
func (u user) checkPassword(password string) bool {
return u.password == password
}
func (u *user) resetPassword(password string) {
u.password = password
}
12、错误处理
- 错误处理 在 go 语言里面符合语言习惯的做法就是使用一个单独的返回值来传递错误信息。
- 不同于 Java 使用的异常。go语言的处理方式,能够很清晰地知道哪个函数返回了错误,并且能用简单的 if else 来处理错误。
- 在函数里面,我们可以在那个函数的返回值类型里面,后面加一个 error, 就代表这个函数可能会返回错误。 那么在函数实现的时候, return 需要同时 return 两个值,要么就是如果出现错误的话,那么可以 return nil 和一个 error。如果没有的话,那么返回原本的结果和 nil。
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name)
if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err)
return
} else {
fmt.Println(u.name)
}
}
13、字符串操作
- 字符串操作go语言使用了strings包当中的方法对字符串进行操作
package main
import (
"fmt"
"strings"
)
func main() {
a := "hello"
fmt.Println(strings.Contains(a, "ll"))
fmt.Println(strings.Count(a, "l"))
fmt.Println(strings.HasPrefix(a, "he"))
fmt.Println(strings.HasSuffix(a, "llo"))
fmt.Println(strings.Index(a, "ll"))
fmt.Println(strings.Join([]string{"he", "llo"}, "-"))
fmt.Println(strings.Repeat(a, 2))
fmt.Println(strings.Replace(a, "e", "E", -1))
fmt.Println(strings.Split("a-b-c", "-"))
fmt.Println(strings.ToLower(a))
fmt.Println(strings.ToUpper(a))
fmt.Println(len(a))
b := "你好"
fmt.Println(len(b))
}
14、格式化输出
- go语言的格式化输出结合了C语言以及Java语言的优势
- 可以很轻松地用
%v 来打印任意类型的变量,而不需要区分数字字符串
- 也可以用
%+v 打印详细结果,%#v 则更详细。
package main
import "fmt"
type point struct {
x, y int
}
func main() {
s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n)
fmt.Println(p)
fmt.Printf("s=%v\n", s)
fmt.Printf("n=%v\n", n)
fmt.Printf("p=%v\n", p)
fmt.Printf("p=%+v\n", p)
fmt.Printf("p=%#v\n", p)
f := 3.141592653
fmt.Println(f)
fmt.Printf("%.2f\n", f)
}
15、结构体的序列化与反序列化
- 要实现与浏览器的交互就要将结构体,对象等序列化成浏览器认识的类型,便于交互,常见的类型有XML,JSON等,JSON是最常用的
- go语言 里面的 JSON 操作非常简单,对于一个已有的结构体,我们可以什么都不做,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用 JSON.marshaler 去序列化,变成一个 JSON 的字符串。
- 序列化之后的字符串也能够用 JSON.unmarshaler 去反序列化到一个空的变量里面。 这样默认序列化出来的字符串的话,它的风格是大写字母开头,而不是下划线。我们可以在后面用 json tag 等语法来去修改输出 JSON 结果里面的字段名。
package main
import (
"encoding/json"
"fmt"
)
type userInfo struct {
Name string
Age int `json:"age"`
Hobby []string
}
func main() {
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
if err != nil {
panic(err)
}
fmt.Println(buf)
fmt.Println(string(buf))
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b)
}
16、时间的处理
- 时间对象是个很重要的对象,许多操作多要依赖于时间
- go语言中的时间处理主要是通过time包下的函数来获取时间以及对时间的格式等进行处理
- 获取当前的时间
- 将时间格式化
- 获取时间的时分秒等相关属性
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println(now)
t := time.Date(2023, 4, 14, 15, 30, 36, 0, time.UTC)
t2 := time.Date(2023, 4, 14, 17, 30, 36, 0, time.UTC)
fmt.Println(t)
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute())
fmt.Println(t.Format("2006-01-02 15:04:05"))
diff := t2.Sub(t)
fmt.Println(diff)
fmt.Println(diff.Minutes(), diff.Seconds())
t3, err := time.Parse("2006-01-02 15:04:05", "2023-04-14 15:30:36")
if err != nil {
panic(err)
}
fmt.Println(t3 == t)
fmt.Println(now.Unix())
}
17、数字解析
- 在前后端交互的过程中,前端响应回来的一般都是JSON等字符串的数据,就需要对字符串当中的数字类型进行解析
- 将字符串与数字进行相互转换
package main
import (
"fmt"
"strconv"
)
func main() {
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f)
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n)
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n)
n2, _ := strconv.Atoi("123")
fmt.Println(n2)
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err)
}
18、进程信息
- 程序的进程信息可以方便我们对程序进行调试
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
fmt.Println(os.Args)
fmt.Println(os.Getenv("PATH"))
fmt.Println(os.Setenv("AA", "BB"))
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf))
}