本人比较看重go的简洁性、跨平台不依赖运行时环境以及高并发(都是相对于Java),同时,我也比较侧重于后端开发,毕竟大部分理工男(懂的都懂)
我也算是开始自己的go语言学习了,但愿不要想java那样…
基础语法#
变量和常量数据类型#
//常量定义
const (
StatusOK = iota + 1 //iota是go语言的一个预定义标识符,表示常量生成器,在const关键字出现时被重置为0,并在每个const声明中自动递增。
StatusBadRequest //2
StatusUnauthorized //3
MB = 1024 * 1024 //1048576
)
//变量定义
func main() {
var str1 string = "Hello Go 1" //标准定义
var str2 = "Hello Go 2" //类型推断
str3 := "Hello Go 3" //短定义(通常用于函数中)
fmt.Println(str1, str2, str3) //output:Hello Go 1 Hello Go 2 Hello Go 3
str1, str2 = str2, str1 //交换str1与str2的值
fmt.Println(str1, str2, str3) // output:Hello Go 2 Hello Go 1 Hello Go 3
}
//空值
func testNonInitValue() {
var a int
var b string
var c float64
fmt.Println(a, b, c) //output: 0 “” 0
//上一行b输出的结果代表b的值是一个空字符串,而不是null或者undefined。
}
//至于类型转换,认真学过Java都知道
...略
//类型自定义
type ll int64 // 定义一个新的类型ll,它的底层类型是int64
//为ll类型实现String方法,使其满足fmt.Stringer接口
func (l ll) String() string {
return fmt.Sprintf("%d", l)
}
//结构体
type UserValue struct {
name string
age int
email string
}
//同理,结构体也可以实现String方法
func (u UserValue) String() string {
return fmt.Sprintf("name:%s, age:%d, email:%s)", u.name, u.age, u.email)
}
// slice
var arr [3]int //只定义,为使用 output: 0,0,0
b := [3]int{1, 2, 3} //临时定义,并且附上初值 output:1,2,3
var c []int //不定长
c1 = append(c, 1,2,3,4,5)
c2 := []int{1,2,3,4,5}
sc1 := make([]int, 0, len(c1)) // make函数创建一个长度为0,容量为len(c1)的切片
sc2 := new ([]int) // new函数创建一个指向长度为0的切片的指针
//map 键值对
m1 := map[string]int{"a": 1, "b": 2} //定义并初始化一个map output: map[a:1 b:2]
m2 := make(map[string]int) //使用make函数创建一个空的map
m2["c"] = 3 //向map中添加一个键值对
for k, v := range m1 { // 使用range关键字遍历map,k代表键,v代表值
fmt.Printf("key: %s, value: %d\n", k, v) //output: key: a, value: 1 \n key: b, value: 2
}go流程控制#
//if语句
if x > 0 {
fmt.Println("x is positive")
} else if x < 0 {
fmt.Println("x is negative")
} else {
fmt.Println("x is zero")
}
//switch语句
switch day := time.Now().Weekday(); day {
case time.Monday:
fmt.Println("It's Monday")
case time.Tuesday:
fmt.Println("It's Tuesday")
default:
fmt.Println("It's another day")
}
//for循环
for i := 0; i < 5; i++ {
fmt.Println(i) //output: 0 1 2 3 4
}
//goto语句
func example() {
fmt.Println("Start")
goto Skip
fmt.Println("This will be skipped")
Skip:
fmt.Println("End")
}
//output: Start \n End
//select语句
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
ch1 <- "Hello from channel 1"
}()
go func() {
time.Sleep(2 * time.Second)
ch2 <- "Hello from channel 2"
}()
select {
case msg1 := <-ch1:
fmt.Println(msg1) //output: Hello from channel 1
case msg2 := <-ch2:
fmt.Println(msg2) //output: Hello from channel 2
case <-time.After(3 * time.Second):
fmt.Println("Timeout")
}
go函数和方法#
//函数定义
func add(a int, b int) int {
return a + b
}
//函数调用
result := add(3, 5) //output: 8
//方法定义
type Rectangle struct {
width float64
height float64
}
func (r Rectangle) Area() float64 {
return r.width * r.height
}
//方法调用
rect := Rectangle{width: 4, height: 5}
area := rect.Area() //output: 20
// 匿名函数
func() {
fmt.Println("This is an anonymous function")
}() //output: This is an anonymous function
// 闭包
func makeAdder(x int) func(int) int {
return func(y int) int {
return x + y
}
}
add5 := makeAdder(5)
result := add5(3) //output: 8
//可变参数
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
result := sum(1, 2, 3, 4) //output: 10go指针#
//指针定义
var p *int //定义一个指向int类型的指针
//指针赋值
x := 10
p = &x //将变量x的地址赋值给指针p
//指针解引用
value := *p //通过指针p获取x的值 output: 10
//指针修改值
*p = 20 //通过指针p修改x的值
fmt.Println(x) //output: 20
//指针与函数
func increment(n *int) {
*n++ //通过指针n修改传入的值
}
num := 5
increment(&num) //传入num的地址
fmt.Println(num) //output: 6
//指针与结构体
type Point struct {
x int
y int
}
p1 := Point{x: 1, y: 2}
p2 := &p1 //创建一个指向p1的指针
p2.x = 3 //通过指针p2修改p1的x值
fmt.Println(p1) //output: {3 2}
//指针与切片
func modifySlice(s []int) {
s[0] = 100 //修改切片的第一个元素
}
slice := []int{1, 2, 3}
modifySlice(slice) //传入切片
fmt.Println(slice) //output: [100 2 3]
//二级指针
x := 10
p := &x
pp := &p
fmt.Println("x:", x, "p:", p, "pp:", pp, "**pp:", **pp) //output: x: 10 p:随机地址 pp: 随机地址 **pp: 10go错误处理#
//error类型
type error interface {
Error() string
}
//defer语句
func example() {
defer fmt.Println("This will be printed last")
fmt.Println("This will be printed first")
}//output: This will be printed first \n This will be printed last
//panic和recover
func example() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("Something went wrong") //触发panic
fmt.Println("This will not be printed")
}//output: Recovered from panic: Something went wronggoError样例:
package main
import (
"fmt"
"os"
"time"
)
const (
TimeFmt = "2006-01-02 15:04:05"
)
func main() {
username, err := queryDatabase(100)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(username)
}
err = readFile("test.txt")
if err != nil {
fmt.Println(err)
}
a := []int{2, 4, 1, 24, 4, 32, 1, 243, 65, 43, 765, 23, 234}
res, err := safeAccess(a, 100)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(res)
}
defres := deferReturn()
fmt.Println("deferResult:", defres)
}
type BusinessError struct {
Code int
Message string
Time time.Time
}
func (e *BusinessError) Error() string {
return fmt.Sprintf("错误代码: %d \n 消息: %s \n 时间:%s \n",
e.Code, e.Message, e.Time.Format(TimeFmt))
}
func queryDatabase(userID int) (string, error) {
if userID <= 0 {
return "", &BusinessError{
Code: 400,
Message: "用户不存在",
Time: time.Now(),
}
}
if userID == 999 { //数据库连接超时
return "", &BusinessError{
Code: 401,
Message: "数据库连接超时",
Time: time.Now(),
}
}
return "李四", nil
}
func readFile(fileName string) error {
file, err := os.Open(fileName)
if err != nil {
return fmt.Errorf("打开文件失败: %w", err)
}
defer file.Close()
buf := make([]byte, 1024)
_, err = file.Read(buf)
if err != nil {
return fmt.Errorf("读取文件失败: %w", err)
}
return nil
}
func safeAccess(arr []int, index int) (result int, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
return arr[index], nil
}
func deferReturn() (result int) {
defer func() {
result++
}()
return 10
}go