如何优雅的入门golang

1,051 阅读5分钟

golang

golang标准库文档

特色

  • 简单、快速、安全
  • 并行、有趣、开源
  • 内存管理、v数组安全、编译迅速

高性能分布式系统开发、海量并行处理、游戏服务端开发再好不过了

一个go程序

package main

import "fmt"

func main() {
    fmt.println("hello world!")
}
$ go run main.go
hello world!

基础组成

  • 包声明 package
  • 引入包 import
  • 函数 func
  • 变量 var
  • 语句 & 表达式
  • 注释 不会被编译
    • // 单行注释
    • /* */ 多行注释

标识符

标识符用来命名变量、类型等程序体。一个或者多个字母[a-zA-Z]、数字[0-9]、下划线_组成, 但是第一个字符必须为_或者字母

  • 有效

    • hello、krc、j、_a、a123、retVal
  • 无效

    • 1abc (首字母不能为数字)、case (关键词)、a+b (出现非约束字符)

关键词

类型 类型 类型 类型 类型
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

预定义

类型 类型 类型 类型 类型 类型 类型 类型 类型
append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr

golang中数据类型

  • 布尔类型 true or false
var b bool = true
var c bool = false
  • 数字类型

整型 int、浮点型 float32、float64,原生支持复数,其中位的运算采用补码

类型 类型 类型 类型
uint8 uint16 uint32 uint64
int8 int16 int32 int64
float32 float64 complex64 complex128
byte rune uint int
uintptr
  • 字符串类型

使用utf-8编码标识unicode文本

  • 派生类型

    • 指针类型 Pointer
    • 数组类型
    • 结构化类型 struct
    • Channel类型
    • 函数类型
    • 切片类型
    • 接口类型 interface
    • Map 类型
var a = "世界你好"
var b string = "hello world"
var c bool

不带声明的只能在函数中体现

package main

var x, y int
var (  // 这种因式分解关键字的写法一般用于声明全局变量
    a int
    b bool
)

var c, d int = 1, 2
var e, f = 123, "hello"

//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"

func main(){
    g, h := 123, "hello"
    println(x, y, a, b, c, d, e, f, g, h)
}

函数定义

func function_name( [parameter list] ) [return_types] {
   函数体
}

数组定义

var var_name [size] var_type

var blance [10] float32

// 初始化数组

var blance = [10]int {1,2,3,4,5,6,7,8,9,10}

指针

指针变量是指向一个值得内存地址 类似于变量和常量,在使用指针变量前也需要声明这个指针

var ip *int

var fp *float32

var a int = 32

ip = &a            
fmt.Printf("a 变量的地址是: %x\n", &a) // 指针的地址

fmt.Printf("*ip 变量的值: %d\n", *ip) // 指针的值

var var_name *var_type

空指针

当一个指针被定义之后没有赋值的话,它的值为nil nil指针也称为空指针

结构体

// 定义一个结构体
type struct_var_type struct {
    member definition;
    member definition;
    member definition;
    member definition;
}

// 声明结构体

var_name := struct_var_type {var1, var2, var3}


type Books struct {
   title string
   author string
   subject string
   book_id int
}

// 声明 Book1 为 Books 类型
var Book1 Books       

Book1.title = "Go 语言"
Book1.author = "ydl"
Book1.subject = "Go语言学习"
Book1.book_id = 123

// 打印这个结构体
fmt.Printf( "Book 1 title : %s\n", Book1.title)
fmt.Printf( "Book 1 author : %s\n", Book1.author)
fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

func printBook(book Books) {
    fmt.Printf( "Book 1 title : %s\n", book.title)
    fmt.Printf( "Book 1 author : %s\n", book.author)
    fmt.Printf( "Book 1 subject : %s\n", book.subject)
    fmt.Printf( "Book 1 book_id : %d\n", book.book_id)
}

// 结构体指针

var struct_pointer *Books

struct_pointer = &Book1

切片

声明一个未定义长度的数组

var var_name [] var_type

或者使用 make()来创建一个切片

var slice1 []type = make([]type, len)

// or

slice1 := make([]type, len)

// 初始化

slice1 :=[] int {1,2,3 } 

类似于python中的切片,取值

s := slice1[start:]
s := slice1[start:end]
s := slice1[:end]

相关函数介绍

len() 获取长度 cap() 测量切片最长长度可以到达多少 append() 追加 copy() 拷贝切片

空切片

未初始化的切片,为nil,长度为0

语言范围 range

range 用于for循环中迭代数组array、切片slice、通道channel、集合map等元素

Map集合

  • 无序的键值对
  • 可以像数组和切片一样迭代
  • 使用hash实现的

定义一个map集合

var map_var_name map[key_data_type] var_type

// 使用make函数
map_var := make(map[key_data_type]var_type)


类型转换

type_name(express)

go 接口类型

把所有具有共性的方法放置在一起,任何其他类型只需要实现这些方法就实现了这个接口

/* 定义接口 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* 定义结构体 */
type struct_name struct {
   /* variables */
}

/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* 方法实现*/
}

错误处理


errors.New("math: square root of negative number")

感想

  • 其实语言还是有很多的通性的,在数据类型和流程控制方面有些差异,但是大致还是一个方向,可能数据类型更丰富了,流程控制更加的方便等 在语言方面增加了很多的特性,使得这个语言解决一些特定的场景需求,比如海量并发、高性能等

  • go 的发展很迅速,开源的库也很多,也有很多出名的开源项目,如:docker容器、TiDB数据库、k8s(Kubernetes)容器编排技术

  • go的社区也比较活跃,在一些一线城市需求量比较大,高性能web服务,游戏后端开发等等

  • 其实我自己开始学php开发的,开发一些web和后端api项目,对于我来说如果再学一些go的web开发,感觉对我的帮助不大,了解自身薄弱之处:

    • 数据结构和算法
    • 网络编程
    • 异步、同步、io操作
    • 设计模式
    • 多线程
    • 数据库
  • 其实编程千变万化不离其中,离不开基础,而这些都是建筑高楼大厦的基础,很多人在开发过程中会遇到瓶颈,不知道如何提升,其实我们可以再次复习以前学过的知识, 温故而知新,读一本书我们可以了解到这本书讲的是什么,第二次读我们可以读到更多,作者写作意图,融入作者的思维,跟随作者置身其中,得到不一样的感受。开发学习亦是如此, 多学习几遍基础,我们会有不一样的感受,视野也会更加的广阔,切勿浮躁,走马观花。热门的框架学习固然重要,跟随时代的潮流,不落伍。但是学习框架也是有迹可循的,在后面我会 介绍如何去学一个框架,入门一个框架,源代码分析,思维导图等等。