Go 谷歌新语言 不损失应用程序性能的情况下降低代码复杂性 具有部署简单 并发性好 语言设计良好 执行性能好的优势
对类C语言的重大改进 能够访问底层操作系统,还提供了强大的网络编程和并发编程支持。
常用于
- 网络编程
- 系统编程
- 并发编程
- 分布式编程
go语言是一门现代编程语言 可用来创建性能卓越的web服务器和系统程序。
go是编译型语言
go version
go version go1.15.1 darwin/amd64
go环境配置
mac@macdeMacBook-Pro ~ % mkdir $HOME/go
mac@macdeMacBook-Pro ~ % mkdir $HOME/go/bin
mac@macdeMacBook-Pro ~ % mkdir $HOME/go/pkg
mac@macdeMacBook-Pro ~ % mkdir $HOME/go/src
export GOPATH=$HOME/go
使用GitHub分享代码mkdir -p $GOPATH/src/github.com/199305a
go hello world
package main
import (
"fmt"
)
func main() {
fmt.Printf("hello wprld")
}
运行helloworldgo run main.go
go的类型
go是一种静态类型语言。数据类型是一种重要的编程计算结构
布尔类型
var b bool
数值var i int = 3
浮点数var f float32 = 0.111
字符串var s string = "foo"
数组var beatles [4]string
类型检查
reflect.TypeOf(s)
类型转换
strconv.FormatBool(b)
变量var s string = "foo"
快捷声明变量
var s,t string = "foo","bar"
var (
x string = "x"
y int = 4
)
变量声明时未赋值使用 默认零值
简短声明变量s := "hello world"
不能在函数外面使用简短变量声明
通常在函数外使用省略类型声明方式
在函数内使用简短变量声明
理解变量作用域
使用指针 &s
s,t := "foo","bar"
fmt.Println(&s,t)
指针传递 打印指针内容 *x
func showMemoryAddress(x *string) {
fmt.Println(x);
fmt.Println(*x);
}
声明常量 const
const greeting string = "hello world"
使用函数
函数是接受输入并返回输出
func addUp(x int,y int) int {
return x + y
}
返回多个值
func getPrize() (int, string) {
i := 2
s := "goldfish"
return i, s
}
定义不定参数函数 可使用3个点
使用具名返回值
func sayHi()(x,y string) {
x = "hello"
y = "world"
return
}
使用递归函数
将函数作为值传递
func anotherFunction(f func() string) string {
return f()
}
func main() {
fn := func() string {
return "function called"
}
fmt.Println(anotherFunction(fn))
}
控制流程 if else elseif
使用if语句
func test() {
b := false
if b {
fmt.Println("b is true")
}
}
使用else语句 else if
使用比较运算符== != >= <= > <
使用算术运算符
+ - * / %
使用逻辑运算符&& || !
使用 switch 语句
func test1() {
i := 2
switch i {
case 1:
fmt.Println("One")
case 2:
fmt.Println("Two")
case 3:
fmt.Println("Three")
default:
}
}
使用for循环 range
func test2() {
i := 0
for i < 10 {
fmt.Println("i is", i)
i++
}
for i := 0; i < 10; i++ {
fmt.Println("i is", i)
}
numbers := []int{1, 2, 3, 4}
for i, n := range numbers {
fmt.Println("The index of the loop is", i)
fmt.Println("The value from the array is", n)
}
}
使用 defer语句 多条语句倒序执行
func test3() {
defer fmt.Println("i am run after the func complete")
fmt.Println("hello world")
}
hello world
i am run after the func complete
数组 切片和映射
使用数组 长度固定var cheese [2]string
使用切片 更加灵活
var cheese = make([]string,2)
在切片添加元素 append
从切片中删除元素 删除索引2处的元素
append(cheese[:2],cheese[2+1:]...)
复制切片中的元素
copy(cheese,cheeses[1:])
使用映射
func test5() {
var players = make(map[string]int)
players["cook"] = 32
players["bairstow"] = 27
players["stokes"] = 26
fmt.Println(players["cook"])
}
从映射中删除元素
delete(players,"stokes")
结构体是什么
结构体是一系列具有指定数据类型的数据字段
type Movie struct {
Name string
Rating float32
}
func test6() {
m := Movie{
Name: "Citizen Kane",
Rating: 10,
}
fmt.Println(m)
}
嵌套结构体
自定义结构体数据字段的默认值
比较结构体 如果结构体类型不同 将会出现编译错误
理解公有和私有值
私有值只能在其所属上下文中使用
要导出结构体及其字段 字段名称必须以大写字母开头
区分指针引用和值引用
结构体是值引用
变为指针引用
n := &m
创建方法和接口
使用方法 附加在实例上
func (m * Movie) summary() string {
}
m.summary()
创建方法集
使用方法和指针
package main
import "fmt"
type Triangle struct {
base float64
height float64
}
func (t * Triangle) changeBase(f float64) {
t.base = f
return
}
func main() {
t := Triangle{base:3,height:1}
t.changeBase(4)
fmt.Println(t.base)
}
使用接口
type Robot interface {
PowerOn() error
}
type R2D2 struct {
Broken bool
}
func (r * R2D2) PowerOn() error {
if r.Broken {
return errors.New("R2D2 is broken")
}else {
return nil
}
}
使用字符串
字符串字面量
s := "I am an interpreted string Literal"
rune字面量
`
s := "I am an interpretedn string Literal"
`
拼接字符串 使用运算符+
s1 :="Oh sweet ignition" + "be my fuse"
intToString := strconv.Itoa(i1)
使用缓冲区拼接字符串
var buffer bytes.Buffer
for i :=0; i < 500;i++ {
buffer.WriteString("z")
}
fmt.Println(buffer)
字符串 字节切片
处理字符串
将字符串转换为小写
fmt.Println(strings.ToLower("VERY BEAUTIFUL"))
在字符串中查找子串
fmt.Println(strings.Index("VERY surface","face"))
删除字符串首位的空格
fmt.Println(strings.TrimSpace("VERY BEAUTIFUL"))
处理错误
错误处理及Go语言的独特之处
file,err := ioutil.ReadFile("foo.txt")
if err != nil{
fmt.Println(err)
return
}
fmt.Println("%s",file)
理解错误类型
创建错误
err := errors.New("Something went wrong")
if err != nil {
fmt.Println(err)
}
从函数返回错误
func Half(numberToHalf int) (int, error) {
if numberToHalf%2 != 0 {
return -1, fmt.Errorf("Cannot half %v", numberToHalf)
}
return numberToHalf / 2, nil
}
错误和可用性
慎用 panic 会终止程序
使用Goroutine 并发
理解并发
并发和并行 并发 多个任务同时执行
并行 任务分成多个部分进行执行
并发就是同时处理很多事情 并行就是同时做很多事情
通过web浏览器来理解并发
阻塞和非阻塞代码
time.Sleep(time.Second * 2)
使用Goroutine处理并发操作
函数前添加go 来是函数异步执行
go test6()
通道简介
使用通道
func slowFunc(c chan string) {
time.Sleep(time.Second * 2)
c <- "slowFunc() finished"
}
func test1() {
c :=make(chan string)
go slowFunc(c)
msg := <-c
fmt.Println(msg)
}
使用缓冲通道 指定通道数量 最后close通道
func slowFunc(c chan string) {
time.Sleep(time.Second * 2)
c <- "slowFunc() finished1"
c <- "slowFunc() finished2"
}
func test1() {
c :=make(chan string,2)
go slowFunc(c)
msg1 := <-c
msg2 := <-c
close(c)
fmt.Println(msg1,msg2)
}
阻塞和流程控制
使用for阻塞流程
func slowFunc(c chan string) {
t := time.NewTicker(1 * time.Second)
for {
c <- "ping"
<-t.C
}
}
func test2() {
message := make(chan string)
go slowFunc(message)
for {
msg := <-message
fmt.Println(msg)
}
}
将通道用作函数参数
<- 位于chan左边 表示制度 位于右边 表示只写
使用select语句 当接收到一条数据时 将不再阻塞
func test3() {
channel1 := make(chan string)
channel2 := make(chan string)
select {
case msg1 := <-channel1:
fmt.Println("received", msg1)
case msg2 := <-channel2:
fmt.Println("received", msg2)
}
}
退出通道case <- stop
func sender(c chan string) {
t := time.NewTicker(1 * time.Second)
for {
c <- "I a messgae"
<-t.C
}
}
func test1() {
messages := make(chan string)
stop := make(chan bool)
go sender(messages)
go func() {
time.Sleep(time.Second * 2)
fmt.Println("Time is up")
stop <- true
}()
for {
select {
case <-stop:
return
case msg := <-messages:
fmt.Println(msg)
}
}
}
使用包实现代码重用
导入包
import (
"fmt"
"time"
)
使用第三方包go get github.com/golang/example/stringutil
func test2() {
s := "ti ercesxsc"
fmt.Println(stringutil.Reverse(s))
}
管理第三方依赖go get u all
GO111MODULE=auto
go run hello.go
创建包
package temperature
func CtoF(c float64)float64 {
return (c * (9 / 5)) + 32
}
func FtoC(c float64)float64 {
return (c - 32) * (9 / 5)
}
Go语言命名约定
Go代码格式设置
使用gofmtgofmt temperature.go
gofmt -w temperature.go
配置文本编辑器
有疑问加站长微信联系(非本文作者)