Golang 特性简介

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")
    }
}
[email protected] 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=.

[email protected] 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
}
[email protected] 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 则样本测试不能通过

[email protected] 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
  • 数组边界检查
时间: 2024-12-29 06:56:47

Golang 特性简介的相关文章

bash特性简介

  1.命令补全.路径补全 Tab:按两次Tab可以给出系统中所有的命令 命令补全:根据给出的字符串在PATH环境变量中定义的路径进行查找:多余一个需要按两次Tab可以给出列表,否则直接补全 路径补全:根据给出的真实路径下的文件名进行补全     2.命令别名 在日常管理和维护linux系统过程中,会使用到大量的命令,有一些很长的命令或用法会经常用到,重复输入会很繁琐,这时可以使用命令别名功能将这个过程简化,提高工作效率 在系统中默认已经定义了一些别名,可以直接使用alias不加任何选项就可以查

CSS3新特性简介

1.CSS3 边框:通过 CSS3,能够创建圆角边框,向矩形添加阴影,使用图片来绘制边框,如border-radius:box-shadow:border-image 2.CSS3 背景:CSS3 包含多个新的背景属性,它们提供了对背景更强大的控制.background-size:background-origin 3.CSS3 文本效果:CSS3 包含多个新的文本特性.text-shadow:word-wrap 4.CSS3 @font-face规则:可将设计师希望使用的字体文件存放到web服

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

1.SQL Server 版本简介 1.1.sql server的版本信息 年    代 版    本 大版本号 1993年 SQL Server for Windows NT 4.21 1994年 SQL Server for Windows NT 4.21a 1995年 SQL Server 6.0 1996年 SQL Server 6.5 1998年 SQL Server 7.0 7.00 2000年 SQL Server 2000 8.00 2003年 SQL Server 2000 E

haproxy的丰富特性简介

HaProxy系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.html 1.简介 官方站点:http://www.haproxy.org haproxy是一款负载均衡软件,它工作在7层模型上,可以分析数据包中的应用层协议,并按规则进行负载.通常这类7层负载工具也称为反向代理软件,nginx是另一款著名的反向代理软件. haproxy支持使用splice()系统调用,它可以将数据在两个套接字之间在内核空间直接使用管道进行传递,无需再在kernel

SpartanBrowser产品和安全特性简介

v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);}/* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colb

温故知新——JS_ ES5新特性简介

ES5浏览器支持情况: 一般来说,除了针对个别特性的特殊说明,各大主流浏览器都支持es5,包括 Chrome 13+ Firefox 4+ Safari 5.1* IE 9* 其中IE9不支持es的严格模式,从IE10开始支持.Safari 5.1不支持Function.prototype.bind. 1.Strict Mode, 即所谓的严格模式. 在一个文件.项目或函数的开头加上"use strict";即开启严格模式. 详细内容参考:参考链接1: 参考连接2: 参考链接3--阮一

PHP7 新特性 简介

整理了一些常用的新特性,欢迎点赞!!! 新增操作符 1.?? $username = $_GET['user'] ?? ''; $username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; 2.<=> $number1 <=> $number2; 当 $number1 小于.等于.大于 $number2 时 分别返回 -1,0,1 新增函数 intdiv(被除数, 除数) — 对除法结果取整 intdiv(3, 2) //

RAID磁盘阵列特性简介

一.RAID概述 RAID是英文Redundant Array of Independent Disks的缩写,翻译成中文即为"独立磁盘冗余阵列",或简称为磁盘阵列.简单的说,RAID是一种把多块独立的物理硬盘或者分区按照不同的方式组合起来,使其在逻辑层面形成统一的一个硬盘组,从而提供比单个硬盘更高的存储性能和提供数冗余的技术.组成磁盘阵列的不同方式称为RAID级别(RAID Levels),注意级别的不同只是表示其组成结构不同,而无性能优劣之分. 二.RAID分类 RAID的实现方式

ASP.NET MVC 常用内置验证特性 简介

0.[DisplayName("名字")] 0.[DisplayName("名字")] 1.[Required] : 必须输入 [Required(ErrorMessage = "请输入用户名")] 2.[StringLength] : 限制字符串长度 [StringLength(10, ErrorMessage = "长度不能超过10个字符")] 3.[Range] : 限制取值范围 1 [Range(0, 120, Err