by sheepbao

主要大概介绍go语言的历史和特性,简单的入门。

来历

很久以前,有一个IT公司,这公司有个传统,允许员工拥有20%自由时间来开发实验性项目。在2007的某一天,公司的几个大牛,正在用c++开发一些比较繁琐但是核心的工作,主要包括庞大的分布式集群,大牛觉得很闹心,后来c++委员会来他们公司演讲,说c++将要添加大概35种新特性。这几个大牛的其中一个人,名为:Rob Pike,听后心中一万个xxx飘过,“c++特性还不够多吗?简化c++应该更有成就感吧”。于是乎,Rob Pike和其他几个大牛讨论了一下,怎么解决这个问题,过了一会,Rob Pike说要不我们自己搞个语言吧,名字叫“go”,非常简短,容易拼写。其他几位大牛就说好啊,然后他们找了块白板,在上面写下希望能有哪些功能(详见文尾)。接下来的时间里,大牛们开心的讨论设计这门语言的特性,经过漫长的岁月,他们决定,以c语言为原型,以及借鉴其他语言的一些特性,来解放程序员,解放自己,然后在2009年,go语言诞生。

思想

Less can be more

大道至简,小而蕴真

让事情变得复杂很容易,让事情变得简单才难

深刻的工程文化

优点

  1. 自带gc。
  2. 静态编译,编译好后,扔服务器直接运行。
  3. 简单的思想,没有继承,多态,类等。
  4. 丰富的库和详细的开发文档。
  5. 语法层支持并发,和拥有同步并发的channel类型,使并发开发变得非常方便。
  6. 简洁的语法,提高开发效率,同时提高代码的阅读性和可维护性。
  7. 超级简单的交叉编译,仅需更改环境变量。(花了我两天时间编译一个imagemagick到arm平台)
  8. 内含完善、全面的软件工程工具。Go语言自带的命令和工具相当地强大。通过它们,我们可以很轻松地完成Go语言程序的获取、编译、测试、安装、运行、运行分析等一系列工作,这几乎涉及了开发和维护一个软件的所有环节。

hello

package main

func main() {
println("hello, sewise")
}

type

主要讲讲特有的类型,其他基本类型不做介绍

slice

切片:可以理解为动态数组,类似c++的vector 声明一个slice

 var slice []T
// 如:
var ints []int

slice的追加

ints = append(ints, 1)
ints = append(ints, 2, 3, 4, 5)

slice的截取

newInts1 := ints[2:3]
newInts2 := ints[2:]
newInts3 := ints[:4]

map

字典:键值对

var json map[string]string

interface

接口:方法的集合,是一种合约 栗子: 声明一个bird接口

var bird interface {
fly()
}

声明一个hen对象(实现bird接口)

type hen struct {
weight int
hasFeather bool
} func (h hen) fly() {
fmt.Println("iI can fly")
} func (h hen) eat() {
h.weight++
fmt.Println("yes, I can eat")
}

声明一个 pig 对象(未实现 bird 接口,因为 pig 不会 fly)

type pig struct {
age int
weignt int
hasFeather bool
} func (p pig) run() {
fmt.Println("I can run")
} func (p pig) eat() {
p.weight += 100
fmt.Println("Yes, I can eat so much")
} func (p pig)sleep(){
fmt.Println("I slept all my life")
} // pig can't fly

channel

通道:轻量集队列,传递某种类型的值的通道

var ch chan int
ch = make(chan int, 1)

往ch写入一个数据

ch<- 8888

从ch读取数据

out := <-ch

特性: channel是有长度的,当channel的缓冲为满时,再往里写入就会阻塞,当channel的缓冲为空时,从channel读就会阻塞

package main

import (
"fmt"
"time"
) func main() {
ch := make(chan int)
fmt.Println("ch len:", len(ch))
go func() {
// 往缓冲满的channel里写数据(阻塞)
// ch <- 1
// 从缓冲为空的channel里读数据(阻塞)
<-ch
fmt.Println("I am in minor goroutine")
}()
fmt.Println("I am in main goroutine")
time.Sleep(2 * time.Second)
}

当长度为 0 是,就是不带缓冲的 channel 长度大于0,就是带缓冲的 channel

并发

关键字:go 启动 go 程 一个普通的函数或方法调用前加上关键字 go,即可启动一个 goroutine

go func() {
fmt.Println("start func")
time.Sleep(120*time.Second)
}()

竞争条件检测 -race race.go

package main

import (
"fmt"
"time"
) func main() {
a := 1
go func() {
a = 2
}()
a = 3
fmt.Println("a is ", a) time.Sleep(2 * time.Second)
}

检测:执行go run -race race.go

a is  3
==================
WARNING: DATA RACE
Write at 0x00c420072188 by goroutine 6:
main.main.func1()
/Users/bao/program/go/gowork/hello/src/research/race.go:11 +0x3b Previous write at 0x00c420072188 by main goroutine:
main.main()
/Users/bao/program/go/gowork/hello/src/research/race.go:13 +0x9f Goroutine 6 (running) created at:
main.main()
/Users/bao/program/go/gowork/hello/src/research/race.go:12 +0x8e
==================
Found 1 data race(s)

结果分析: goroutine6运行到第11行和main goroutine运行到13行的时候触发竞争了。而且goroutine6是在第12行的时候产生的。

package

包的管理,关键字import,GOPATH

gopath

gopath是一个路径列表,存放go项目工程 GOPATH文件目录结构

├── bin  二进制文件目录
├── pkg 编译好的库文件目录
└── src 源码目录

平常项目的目录结构

├── bin  二进制文件目录
├── pkg 编译好的库文件目录
└── src 源码目录
├── main 入口函数目录
└── vendor 当前项目的库目录
└── sheepbao.com
└── glog

import

比如上面的项目,我要在main.go引入glog包

package main

// 引入glog包
import "sheepbao.com/glog" func main() {
glog.Println("test")
}

go的工程工具简介

test

go的命令工具 test,用来做测试

单元测试

go test 只测试函数名被它正确匹配的测试函数 go test -v -run="French|Canal"

栗子: add.go

package test

func addOne(i int) int {
return i + 1
}

add_test.go

package test

import "testing"

func TestAddOne(t *testing.T) {
result := addOne(1)
if result != 2 {
t.Error("1+1!=2")
}
}
bao@baoMac test$ go test -v .
=== RUN TestAddOne
--- PASS: TestAddOne (0.00s)
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/test 0.006s

基准测试

go test -bench=. 内存的分配情况 go test -bench=FuncName -benchmem 栗子: stringsCon.go

package bench

import (
"fmt"
) func Sprintf(s1, s2, s3 string) string {
return fmt.Sprintf("%s%s%s", s1, s2, s3)
} func AddString(s1, s2, s3 string) string {
return s1 + s2 + s3
}

stringCon_test.go

package bench

import "testing"

var (
s1 = "make it run!"
s2 = "make it right!"
s3 = "make it fast!"
) func BenchmarkSprintf(b *testing.B) {
for i := 0; i < b.N; i++ {
Sprintf(s1, s2, s3)
}
} func BenchmarkAddString(b *testing.B) {
for i := 0; i < b.N; i++ {
AddString(s1, s2, s3)
}
}

go test -bench=.

bao@baoMac bench$ go test -bench=.
testing: warning: no tests to run
BenchmarkSprintf-4 5000000 349 ns/op
BenchmarkAddString-4 20000000 61.7 ns/op
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/bench 3.414s

样本测试

package et

import (
"fmt"
) func ExampleHello() {
fmt.Println("hello, sewise")
// Output: hello, sewise
}
bao@baoMac example$ go  test -v .
=== RUN ExampleHello
--- PASS: ExampleHello (0.00s)
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/example 0.006s

如果把上面的// Output: hello, sewise改为// Output: hello, sewis 则样本测试不能通过

bao@baoMac example$ go  test -v .
=== RUN ExampleHello
--- FAIL: ExampleHello (0.00s)
got:
hello, sewise
want:
hello, sewis
FAIL
exit status 1
FAIL _/Users/bao/program/go/gowork/hello/src/research/example 0.006s

pprof

go的命令工具 pprof,用来性能分析(内存使用,泄露和cpu消耗) go tool pprof

可视化(原是svg文件,下图为截图):

可视化(原是 svg 文件,下图为截图:

go tool pprof --text http://localhost:6060/debug/pprof/heap

go命令教程

资料

http://www.csdn.net/article/2012-07-04/2807113-less-is-exponentially-more

http://www.jianshu.com/p/91e40c3e3acb?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

http://smallsoho.com/2016/11/20/Go简明教程.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

大牛真身

最大牌的当属B和C语言设计者、Unix和Plan 9创始人、1983年图灵奖获得者Ken Thompson,这份名单中还包括了Unix核心成员Rob Pike(go语言之父)、java HotSpot虚拟机和js v8引擎的开发者Robert Griesemer、Memcached作者Brad Fitzpatrick,等等。

功能

  • 规范的语法(不需要符号表来解析)
  • 垃圾回收(独有)
  • 无头文件
  • 明确的依赖
  • 无循环依赖
  • 常量只能是数字
  • int和int32是两种类型
  • 字母大小写设置可见性(letter case sets visibility)
  • 任何类型(type)都有方法(不是类型)
  • 没有子类型继承(不是子类)
  • 包级别初始化以及明确的初始化顺序
  • 文件被编译到一个包里
  • 包package-level globals presented in any order
  • 没有数值类型转换(常量起辅助作用)
  • 接口隐式实现(没有“implement”声明)
  • 嵌入(不会提升到超类)
  • 方法按照函数声明(没有特别的位置要求)
  • 方法即函数
  • 接口只有方法(没有数据)
  • 方法通过名字匹配(而非类型)
  • 没有构造函数和析构函数
  • postincrement(如++i)是状态,不是表达式
  • 没有preincrement(i++)和predecrement
  • 赋值不是表达式
  • 明确赋值和函数调用中的计算顺序(没有“sequence point”)
  • 没有指针运算
  • 内存一直以零值初始化
  • 局部变量取值合法
  • 方法中没有“this”
  • 分段的堆栈
  • 没有静态和其它类型的注释
  • 没有模板
  • 内建string、slice和map
  • 数组边界检查

Golang 特性简介的更多相关文章

  1. ES6新特性简介

    ES6新特性简介 环境安装 npm install -g babel npm install -g babel-node //提供基于node的REPL环境 //创建 .babelrc 文件 {&qu ...

  2. SpartanBrowser产品和安全特性简介

    v:* { } o:* { } w:* { } .shape { }p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-botto ...

  3. AsyncLocal 与 ThreadLocal ThreadStatic特性简介

    AsyncLocal 与 ThreadLocal [.NET深呼吸]基于异步上下文的本地变量(AsyncLocal) https://www.cnblogs.com/tcjiaan/p/5007737 ...

  4. [转帖]sql server版本特性简介、版本介绍简介

    sql server版本特性简介.版本介绍简介 https://www.cnblogs.com/gered/p/10986240.html 目录 1.1.sql server的版本信息 1.2.版本重 ...

  5. haproxy的丰富特性简介

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  6. sql server版本特性简介、版本介绍简介

    1.SQL Server 版本简介 1.1.sql server的版本信息 年    代 版    本 大版本号 1993年 SQL Server for Windows NT 4.21 1994年 ...

  7. ECMAScript 6新特性简介

    目录 简介 ECMAScript和JavaScript的关系 let和const 解构赋值 数组的扩展 函数的扩展 简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言 ...

  8. ECMAScript 2016(ES7)新特性简介

    简介 自从ES6(ECMAScript 2015)在2015年发布以来,ECMAScript以每年一个版本的速度持续向前发展.到现在已经是ECMAScript 2020了. 每个版本都有一些新的特性, ...

  9. ECMAScript 2017(ES8)新特性简介

    目录 简介 Async函数 共享内存和原子操作 Object的新方法 String的新方法 逗号可以添加到函数的参数列表后面了 简介 ES8是ECMA协会在2017年6月发行的一个版本,因为是ECMA ...

随机推荐

  1. [转]Linux联网问题

    一.Kali联网问题 首先ifconfig,可以看到没有正在工作的网卡,只有localhost 然后ifconfig -a,可以看到eth0这块网卡并没有离家出走,只是罢工了而已 打开/etc/net ...

  2. G. (Zero XOR Subset)-less(线性基)

    题目链接:http://codeforces.com/contest/1101/problem/G 题目大意:给你n个数,然后让你把这n个数分成尽可能多的集合,要求,每个集合的值看做这个集合所有元素的 ...

  3. usb的一些网址

    一些关于usb的帖子.网址: usb gadget device g_ether.ko 做成usbnetwork http://bbs.csdn.net/topics/370120345 Linux ...

  4. Daemon函数的用法

    Daemon函数的用法 说明: 让一个程序后台运行. 原型: #include <unistd.h> int daemon(int nochdir, int noclose); #incl ...

  5. Linux硬盘的检测(原创)

    http://czmmiao.iteye.com/blog/1058215 概述 随着硬盘容量.速度的快速发展,硬盘的可靠性问题越来越重要,今天的单块硬盘存储容量可轻松达到1TB,硬盘损坏带来的影响非 ...

  6. ASP.NET结合COM组件发送Email

    在开发电子邮件发送程序的时候,我们经常需要使用到相应的组件,其实不需要第三方的组件(例如:Jmail)照常可以做到发送Email的功能. 在系统目录(如c:/winnt或c:/windows)的sys ...

  7. poj1093

    题意:给出一个句子和要求整理后每行包含的字符数,要求将其整理为一种总badness最小的形式.设每个空格长度为n,单个空格的badness计算公式为(n-1)^2.总badness等于所有空格的bad ...

  8. 使用配置文件启动MongoDB

    Ubuntu 16.04 (阿里云ECS),MongoDB 4.0, 原来,已经写了10篇MongoDB的随笔了.可是,自己居然没有使用配置文件启动过MongoDB,对其更多的配置是不明白的. 昨天( ...

  9. 【前端开发】移动端适配方案js,rem单位转换,640设计稿20px=1rem

    ! function() { var style = document.createElement("STYLE"), docEl = document.documentEleme ...

  10. CAS5.2x单点登录(一)——搭建cas服务器

    系列文章列表: https://blog.csdn.net/u013825231/article/category/7517313 单点登录的介绍 单点登录(Single Sign On ,简称SSO ...