Golang背景
Go(又称Golang) Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。
作者:罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go。
- Robert Griesemer:曾协助实现 Java 的 HotSpot 编译器和 JavaScript V8 引擎。
- Rob Pike:曾是贝尔实验室的 Unix 团队和 Plan9 操作系统成员,与 Thompson 一起创造了 UTF-8 字符编码。
- Ken Thompson:不用多说了,技术圣殿的人物,创造了 C 语言和 Unix,获得了 1983 年图灵奖和 1988 国家技术奖。
百度百科上有详细的介绍。
Go的优点
- Go 极其地快速。其性能与 Java 或 C++相似。Go 一般比 Python 要快 30 倍。
- GO开发效率非常的高,非常容易上手,相对于JAVA。
- GO并发性&通道,Goroutines 是 Go 面向线程的轻量级方法,而通道是 goroutines 之间通信的优先方式。创建 Goroutines 的开销,只需几千个字节的额外内存,可支持非常高的并发数。
- Go 编写的服务编译时间相较于 Java要优很多。
- 强大的生态系统:Go 有着强大的工具支持,面向 Redis、RabbitMQ、PostgreSQL、Template parsing、Task scheduling、Expression parsing 和 RocksDB 的稳定的库。
- GOFMT格式化工具:和python类似,强化代码格式,让代码层次更清晰。
Golang(window / linux)安装、配置
日前支持MacOS、windows、linux操作系统
安装包下载地址(https://golang.google.cn/dl/)
go1.12.1百度网盘下载
链接:https://pan.baidu.com/s/1-91EllaD9yvveNyt88-yZA
提取码:0o8e
windows安装
1、 一般用msi文件,按照提示步骤安装即可;
2、环境变量配置:创建GOROOT
值为golang的安装目录;path中加入%GOROOT%\bin
;最后一个比较重要就是GOPATH
,表示Go的工作目录,项目所要用到的库包下载到这里,由个人指定;
linux安装
1、下载go压缩包并解压;
2、与windows类似设置环境变量;
vim /etc/profile 对PATH、GOROOT、GOPATH进行设定;
source /etc/profile 使修改生效;
验证安装
命令:go version
输出版本信息:go version go1.8 linux/amd64
组件仓库
如上图,通过go get 命令下载所需组件。
go get github.com/go-martini/martini //下载WEB 应用框架
Hello World
还是贯例从hello world开始我们的go语言编程之旅。
package main //Go程序执行的入口都是main包的main方法,而java可以指定执行类默认也是从main开始执行
import "fmt" //引入格式输入包,类似于java的System.out
func 方法(){ //支持中文作为方法名,但不建议
fmt.Println("调用中文方法!")
}
func main(){
方法();
fmt.Println("Hello","World","!")
fmt.Println("Hello World !")
}
Java与Go对比
包概念,引入包
- java的包是类和接口的集合,包的路径就是文件夹层次结构;用
import
引入的是具体的类 - go的包是各种功能的集合(没有java类的概念),包名不一定与所在文件夹名相同;用
import
是包的(%GOROOT%\src
或%GOPATH%\src
下)文件存储路径,可以与实际包名无关,但建议与包名保持一致,由于go没有类的概念,而是用包名来调用
访问控制
- java 访问控制一般由
private
、protected
、default
、public
- go访问控制由私有和公共两种,以大写字母开头的常量
const
,结构体struct
,方法func
继承与接口、多返回值
- java 继承
extends
父类与子类的关系; 接口interface
一组、一类事物的特性抽象,必须先定义接口再实现,用implements
耦合关系;无多返回值 - go 一个
struct
(结构体)嵌套植入另一个struct
来实现类似的继承概念;接口非耦合的方式,接口和实现的方法没有显式的绑定定义,定义顺序也无限制;有多返回值
package main //Go程序执行的入口都是main包的main方法,而java可以指定执行类默认也是从main开始执行
import "fmt" //引入格式输入包,类似于java的System.out
type Being struct {
IsLive bool
}
type Human struct {
Being
Name string
Age int
}
func (h Human) Eat(){
fmt.Println("human eating...")
h.Drink()
}
func (h Human) Drink(){
fmt.Println("human drinking...")
}
type Student struct {
Human
Grade int
Major string
}
func (h Student) Eat(){ //覆盖Human结构的方法
fmt.Println("Student eating...")
}
func (h Student) Study(){ //Student结构特有的方法
fmt.Println("Student studying...")
}
type IEat interface {
Eat()
}
type IDrink interface {
Drink()
}
type IStudy interface {
Study()
}
/**
* value: IDrink 的默认实例;
* b: bool 类型,表明断言是否成立;
* s : Student的实例
* IDrink : 接口
**/
func main(){
s :=Student{Grade: 1, Major: "English", Human: Human{Name: "Jason", Age: 12, Being: Being{IsLive: true}}}
value, b := interface{}(s).(IDrink)
fmt.Println(value, b)
}
默认值
- java中类成员变量会初始化默认值,但方法内的局部变量需要进行初始化,否则会报错,空值以null表示,null是一个关键词
- go中的所有字段都有对应的(默认值)零值,指针、通道、函数、接口、映射或切片的(空值)零值为nil,而nil不是一个关键词,但不建议对他进行重新定义
指针
- java 中没有指针的概念,对象(非基本类型)的地址不能直接获取,实例对象的地址包含在对象句柄中
- go 中有指针的概念,也就是对象存储的地址,& 为取地址操作,* 为取值操作,& 与 * 是一对互补操作符
package main //Go程序执行的入口都是main包的main方法,而java可以指定执行类默认也是从main开始执行
import "fmt" //引入格式输入包,类似于java的System.out
func main(){
var s string ="abc"
var ss = &s //取s的地址,ss则为一个字符类型指针
var sss = &ss //取ss指针的类型,sss则为一个指针地址类型的指针
fmt.Println(sss,ss,*ss)
}
go程、channel
- go程可心说就相当于java中的线程,只是go程相当简单,只要go 方法()就可以启动go程模块
- channel与java不同的是go程之间可以用channel来进行通信,通过成对的发送和接收来完成数据传递
package main
import (
"fmt"
"time"
"strconv"
)
const (
NormalTimeFormat string = "2006-01-02 03:04:05 PM"
)
func routinefun(no string,ch chan<-string){
fmt.Println("before:",no,time.Now().Format(NormalTimeFormat))
ch <- ("in routinefun ("+no+")"+time.Now().Format(NormalTimeFormat))
fmt.Println("after:",no,time.Now().Format(NormalTimeFormat))
}
func main(){
ch :=make(chan string)
for i:=0 ;i<5 ;i++{
go routinefun("no"+strconv.Itoa(i),ch)
}
for i:=0 ;i<5 ;i++{
fmt.Println(<-ch)
}
}
编码特征
Go风格特点(去除多余的包和变量,变量定义可以是var name [type],也可以是var name =实例,也可以是name := 实例,进行自我推导类型; 每行程序结束后不需要撰写分号(;) ;大括号({)不能够换行放置;if判断式和for循环不需要以小括号包覆起来;
简而言之:简单!简洁!
有疑问加站长微信联系(非本文作者)