go语言学习指南

2017/05/23 go

本文主要就go语言的学习发展,总结自己在学习的道路上遇到的问题,同时对学习资源进行归纳总结,以方便共同学习

概述

近年来语言的飞速发展,的确给大家带来一种应接不暇的现象,究竟如何取舍,的确是让人挺纠结的。自从Google宣布,kotlin 作为android开发的首选语言,java的地位能否像以前一样不得而知,但是基于jvm的语言(Groovy,Kotlin)的发展也让大家看到每种语言在处理特定问题的优势;gradle基于groovy,开发新一代的构建工具,个人觉得你极大提高了生产力,在持续集成领域,无疑增加了一剂猛药。可以看到groovy在领域特定语言上的优势。

  • 客户端 客户端领域需要一种高效,快速实现业务的语言
  • 服务端 J2EE开发不断的发展,在起初搭建项目时,过多而又繁琐的配置,让人觉得java越来越臃肿;微服务的出现似乎要打破这种令人窒息的垂直架构,转而向分布式系统进发,spring boot的诞生就可以看出来;此前各种RPC框架的也在服务化打下良好的基础 docker虚拟化技术,似乎需要一种简洁的方式来实现web端的开发,是否有一种语言能够做到轻量级,答案是go语言

一.学习指引

语言的发展总是相互学习,因此对比式的方法能帮助我们快速理解新语言的新特性

1.1 Go 语言安装

Gvm 安装

bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

执行gvm install go1.8.1出现以下错误:

##### Building Go bootstrap tool.

cmd/dist

ERROR: Cannot find /home/liaojinlong/go1.4/bin/go.

Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.

先安装go1.4

gvm install go1.4 -B

1.2 Go开源项目安装方法

NOTE: 这里解释一下安装过程中出现的问题,方便以后追溯 go安装,推荐gvm方式安装,类似node的npm,ruby的rvm

  • go get 无法下载github项目,可以使用如下类似的命令手动下载项目
git clone https://github.com/revel/examples.git $GOPATH/src/github.com/revel/examples

开发工具JetBrain

  • 激活activeserver
http://idea.iteblog.com/key.php
  • 安装go plugin

image

二.基本要点

2.1 基本数据结构

  • array
  • slice 两者定义的的区别
  • point
  • Map map取值的多值返回特性

Test that a key is present with a two-value assignment:

elem, ok = m[key]
 package main

import "fmt"

func main() {
  m := make(map[string]int)

  m["Answer"] = 42
  fmt.Println("The value:", m["Answer"])

  m["Answer"] = 48
  fmt.Println("The value:", m["Answer"])

  delete(m, "Answer")
  fmt.Println("The value:", m["Answer"])

  v, ok := m["Answer"]
  fmt.Println("The value:", v, "Present?", ok)
}
  • Func 多值返回 函数也是值。他们可以像其他值一样传递,比如,函数值可以作为函数的参数或者返回值
package main

import (
  "fmt"
  "math"
)

func compute(fn func(float64, float64) float64) float64 {
  return fn(3, 4)
}

func add (fn func(int,int) int) int{
  return fn(1,2)
}

func main() {
  
  fmt.Println(compute(func(x, y float64) float64 {
    return math.Sqrt(x*x + y*y)
  }))
  
  fmt.Println(add(func(x,y int) int {
    return x+y
  }))
}

  • 闭包 闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)
 package main

import "fmt"

func adder() func(int) int {
  sum := 0
  return func(x int) int {
    sum += x
    return sum
  }
}

func main() {
  one := adder()
  fmt.Println(one(1))
  
}
  • method

Go 没有类。然而,仍然可以在结构体类型上定义方法。方法接收者 出现在 func 关键字和方法名之间的参数中

package main

import (
  "fmt"
  "math"
)

type Vertex struct {
  X, Y float64
}

func (v *Vertex) Abs() float64 {
  return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
  v := &Vertex{3, 4}
  fmt.Println(v.Abs())
}

method和func在定义上有类似之处

2.2 面向对象

2.2.1 struct

由于go语言中没有对象的概念,需要借助method和struct实现多态的特性

package main

  import (
    "fmt"
    "math"
  )

  type Rectangle struct {
    width, height float64
  }

  type Circle struct {
    radius float64
  }

  func (r Rectangle) area() float64 {
    return r.width*r.height
  }

  func (c Circle) area() float64 {
    return c.radius * c.radius * math.Pi
  }


  func main() {
    r1 := Rectangle{12, 2}
    r2 := Rectangle{9, 4}
    c1 := Circle{10}
    c2 := Circle{25}

    fmt.Println("Area of r1 is: ", r1.area())
    fmt.Println("Area of r2 is: ", r2.area())
    fmt.Println("Area of c1 is: ", c1.area())
    fmt.Println("Area of c2 is: ", c2.area())
  }

2.2.2 interface

go语言没有implement关键字,接口的实现利用method实现

type Human struct {
    name string
    age int
    phone string
  }

  type Student struct {
    Human //匿名字段Human
    school string
    loan float32
  }

  type Employee struct {
    Human //匿名字段Human
    company string
    money float32
  }

  //Human对象实现Sayhi方法
  func (h *Human) SayHi() {
    fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
  }

  // Human对象实现Sing方法
  func (h *Human) Sing(lyrics string) {
    fmt.Println("La la, la la la, la la la la la...", lyrics)
  }

  //Human对象实现Guzzle方法
  func (h *Human) Guzzle(beerStein string) {
    fmt.Println("Guzzle Guzzle Guzzle...", beerStein)
  }

  // Employee重载Human的Sayhi方法
  func (e *Employee) SayHi() {
    fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
      e.company, e.phone) //此句可以分成多行
  }

  //Student实现BorrowMoney方法
  func (s *Student) BorrowMoney(amount float32) {
    s.loan += amount // (again and again and...)
  }
  //Employee实现SpendSalary方法
  func (e *Employee) SpendSalary(amount float32) {
    e.money -= amount // More vodka please!!! Get me through the day!
  }

  // 定义interface
  type Men interface {
    SayHi()
    Sing(lyrics string)
    Guzzle(beerStein string)
  }

  type YoungChap interface {
    SayHi()
    Sing(song string)
    BorrowMoney(amount float32)
  }

  type ElderlyGent interface {
    SayHi()
    Sing(song string)
    SpendSalary(amount float32)
  }

NOTE: go语言中没有类的概念,想实现面向对象的设计,需要依赖type自定义类型,然后利用method方法实现

type MyInterface interface{
    someMethod() 
}
type MyType struct{}
var _ MyInterface = &MyType{}
上面方法会报错,因为其并没有定义someMethod方法,代表其没有实现MyInterface接口
实现MyInterface的 method如下
func (myType *MyType) someMethod()
  • 空interface

    任意的类型都实现了空interface(我们这样定义:interface{}),也就是包含0个method的interface 一个函数把interface{}作为参数,那么他可以接受任意类型的值作为参数,如果一个函数返回interface{},那么也就可以返回任意类型的值

  • 隐式接口

    有点类型java interface的继承关系,用于扩展接口方法

  • 反射

2.3 并发

三.高级进阶

3.1 网络编程

3.2 开源框架

开源项目是进一步学习一门语言的敲门砖,每当你感觉技术瓶颈的时候,开源项目总能改你带来意外的惊喜,因此学习别人的代码也是在促进自己进步。这里推荐的开源项目包括一种框架提供解决问题的整体方案;一个独立项目能够独立完成一项业务需求即可

3.3 分布式系统设计

参考资料

工具彩蛋

Search

    Post Directory