这是我参与【第五届青训营】笔记创作活动的第1天
😻😻😻😻😻😻😻😻😻😻😻😻😻😻😻😻😻😻😻
写在前面: 本篇文章大概字数3000字,阅读时间6min。包括go介绍,环境配置、语言基础。其中语言基础方面,有关条件语句、循环语句等不再赘述,本人仅仅挑选一些对我来说go比较特别的语法进行分享。。。。。。
1.1 Go(Golang)简介
-
WIKI
-
特点
高性能、高并发、语法简单、学习曲线平缓、丰富的标准库、完善的工具链、静态链接、快速编译、跨平台、垃圾回收
1.2 环境配置
1️⃣ 安装Golang
- go.dev/
- studygolang.com/dl
- goproxy.cn (上述第二个网站的补偿,提升下载速度)
2️⃣ IDE的选择
推荐:
1.3 Hello World
package main
import{
"fmt"
}
func main(){
fmt.Println("hello world")
}
1.4 Go语言基础—变量
变量类型: 字符串 整形 浮点型 布尔型
变量定义方法:
//1.字符串类型直接赋常量 , boolean型雷同
var a = "first"
var Boo = true
//2. var声明变量类型
var b, c int = 1, 3
//3. := 赋值
f := float32(e)
//4. const赋值
const s string = "constant"
const h = 500000
1.5 Go语言基础—切片
go语言切片是go语法的一大特点,与python语法类似,Go 语言切片是对数组的抽象。Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
-
定义切片:
//1.声明一个未指定大小的数组来定义切片 var identifier []type //2. 使用 make() 函数来创建切片 var slice1 []type = make([]type, len) //3. 指定容量定义 make([]T, length, capacity) -
切片常见操作:
/* 创建切片 */ numbers := []int{0,1,2,3,4,5,6,7,8} /* 打印子切片从索引1(包含) 到索引4(不包含)*/ fmt.Println("numbers[1:4] ==", numbers[1:4]) //[1 2 3] /* 默认下限为 0*/ fmt.Println("numbers[:3] ==", numbers[:3]) //[0 1 2] /** 如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。 下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。 */ /* 向切片添加一个元素 */ numbers = append(numbers, 1) //[0,1,2,3,4,5,6,7,8,1] /* 同时添加多个元素 */ numbers = append(numbers, 2,3,4) //[0,1,2,3,4,5,6,7,8,1,2,3,4]
1.6 Go语言基础—函数
由于本人常用语言为java,因此我认为go语言的函数也是非常与众不同的一点,Golang里面的函数原生支持返回多个值。在实际的业务逻辑代码里面几乎所有的函数都返回两个值,第一个是真正的返回结果,第二个值是一个错误信息。
package main
import "fmt"
func exists(m map[string]string, k string)(v string, ok bool){
v, ok = m[k]
return v, ok
}
1.7 Go语言基础 — 结构体方法
在Golang里面可以为结构体去定义一些方法。会有点类似于其他语言里面的类成员函数,
其中我认为,方法的本质是函数,但是方法和函数又具有不同点。
Go 方法是作用在接收者(receiver)上的一个函数,接收者是某种类型的变量。因此方法是一种特殊类型的函数。
接收者类型可以是(几乎)任何类型,不仅仅是结构体类型:任何类型都可以有方法,甚至可以是函数类型,可以是 int、bool、string 或数组的别名类型。
方法的格式:
func (recv receiver_type) methodName(parameter_list) (return_value_list) { … } func (_ receiver_type) methodName(parameter_list) (return_value_list) { … }
函数与方法的区别:
- 函数将变量作为参数:Function1(recv)
- 方法在变量上被调用:recv.Method1()
如以下例子中
package main
import "fmt"
type user struct {
name string
password string
}
func (u user) checkPassword( password string) bool {
return u.password e= 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")) // true
}
我们将checkPassword与resetPassword两个普通函数修改为了结构体方法,这样的话用户就可以通过a.checkPassword(”xxx”)的方式去调用
同时在实现结构体方法的时候也有两种方式
- 带指针方式
- 该方法可以对结构体本身进行修改
- 不带指针方式
- 操作的只是结构体的一个拷贝,无法对原结构体进行修改
1.8 Go语言基础 — 错误处理
相比于其他语言而言,Go 语言通过内置的错误接口提供了非常简单的错误处理机制。error类型是一个接口类型,它的定义如下:
type error interface {
Error() string
}
我们可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现
}
在下面的例子中,我们在调用Sqrt的时候传递的一个负数,然后就得到了non-nil的error对象,将此对象与nil比较,结果为true,所以fmt.Println(fmt包在处理error时会调用Error方法)被调用,以输出错误,如下所示
result, err:= Sqrt(-1)
if err != nil {
fmt.Println(err)
}
1.9 Go语言基础 — json处理
Go留给我的一个更深的印象便是它的json处理方式,go中的json操作非常的方便,对于一个已有的结构体,我们可以什么都不做,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用JSON.marshaler 去序列化,变成一个JSON 的字符串。
序列化之后的字符串也能够用JSON.unmarshaler 去反序列化到一个空的变量里面。 这样默认序列化出来的字符电的话,它的风格是大写字母开头,而不是下划线,我们可以在后面用 json tag 等语法来去修改输出 JSON 结果里面的字段名
使用go的json处理方法如下所示
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) // [123 34 78 97...]
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
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) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}
小结
经过一天的青训,让我对go的认知更加加深了,go的高效是肉眼可见的,拿最简单的例子来说,我们平时在leetcode进行刷题时,对于相同逻辑的代码,java 与 go的运行内存消耗竟然相差10倍之多,这也解释了为什么go能够去做那些容器化技术,去把一些服务做的那么轻量级。相信随着时代的变迁,go的生态也能做的够越来越好吧!!