码迷,mamicode.com
首页 > 其他好文 > 详细

golang

时间:2015-08-27 23:15:06      阅读:812      评论:0      收藏:0      [点我收藏+]

标签:golang   goroutine   高并发   函数多返回值   多重赋值   

 go语言特性:

◆ 自动垃圾回收

具备系统自动释放资源

◆更丰富的内置类型

map类型、slice类型(类似vector)

◆函数多返回值

lua/erlang一样,支持函数多返回值,优化输入输出参数、结构体参数等传递

◆错误处理

defer/recover/panic,

defer用于资源的释放,go语言不提供构造和析构,

recover截取错误处理流程,一般在使用defer的关键字函数中使用;若在无异常的goroutine中使用recover,会导致此goroutine所在的进程打印错误信息后,直接退出

◆匿名函数

a := fun() / a();

◆类型、接口

类型struct,类似C的结构体,但不支持继承和重载;

接口:非入侵式接口、interface{}作为函数参数,可传递任何类型

◆并发

吸取erlang语言的面向消息编程机制,所有的数据交互都用goroutine的消息传递

◆反射

模仿java语言的反射特性,但不像java内置类型工厂

◆语言的交互性

go语言通过Cgo库,可混合编写C语言代码

技术分享

golang并发:

        golang为实现高并发性,引入了goroutine,通过channel模式用CSP(通信顺序进程,Communicating Sequential Process)模型实现goroutine之间的数据交互;

        golang的并发系统,由N个并行运行的CSP组成,每个CSP之间都是资源独立的,通过go提供的通信原语进行消息传递,通过类似管道的channel模式,来实现CSP,从而达到跨越goroutine的通信。

        此外,一个进程中的所有协程goroutine都在同一个内存空间中,所以不同的goroutine要去访问共享的内存变量时,需要访问读写锁,由go语言的sync库提供读写锁功能。

 

作用域:

小字母开头命名,只包内可见

大字母开头命名,包内外可见

适用于变量、类型、函数

 

go内置数据类型:

布尔bool

bool类型值只有truefalse,不能复制为数值10

◆ 整型:

int8/byte(uint8)/int16/uint16/int32/uint32/int64/uint64/int/uint/uintptr

int/uint:平台相关,324字节,648字节

uintptr :平台相关指针

intint32 :go语言认为是两种类型,go语言不支持隐式类型转换,而且不支持不同类型的比较,比较必须是严格的“相同”类型,类型转换必须显示强转;若比较int32int16类型的,编译器会报错;给变量赋值时,a := 12b := 12.0会对变量类型进行自动推导,a为整型,b为浮点型。

◆ 浮点型float32/64

v1 := 12.0,系统进行自动推导时,v1float64类型的

◆ 复数complex64/128

数学上的复数:3.2 + 12i,具备实部与虚部的概念

◆ 字符串string

go语言的string类型是内置的

◆ 字符rune

byte(uint8) : 代表utf-8的字符类型,占一个字节

rune : 代表Unicode字符,go标准库的unicode包提供相关操作,unicode/utf-8的包提供unicode/utf-8之间的转换

◆ 错误error

◆ 指针pointer

◆ 数组array

[32]byte // 长度为32的数组,每个元素为一个字节
[2*N] struct{ x, yint32} //复杂类型数组
[1000]*float64//指针数组
[3][5]int // 二维数组
[2][2][2]float64//等同于[2]([2]([2]float64))

注意:数组是值类型,故作为函数参数传递时,是值传递,传递的是一个数组的副本,即作为函数参数传递的数组是无法被修改的

◆ 切片slice

类似vector,具备cap容量的概念

slice的创建:创建、基于数组创建、基于切片创建

myArr := {1,2,3,4,5}

mySlice := myArr[:5]        //myArr[first : last],用myArr的前5个元素创建Slice

mySlice := make([]int, 5)   //创建5个为0Slice

mySlice := make([]int, 5, 10)   //len(mySlice)5cap(mySlice)10

mySlice := []int{1,2,3,4,5}

oldSlice := []int{1,2,3,4,5}

newSlice := oldSlice[:6] ==>oldSlice的元素个数不足,用0补全newSlice

sliceappend:切片内容的附加

mySlice := []int{1,2,3,4,5}

mySlice = append(mySlice, 1,2,3)    //第二个参数以右边的是不定参数类型

 

mySlice2 := []int{8,9,10}

mySlice = append(mySlice, mySlice2 ...)    

//不定参数,省略号;第二个参数mySlice2后面加了三个点,即一个省略号,如果没有这个省
略号的话,会有编译错误,因为按append()的语义,从第二个参数起的所有参数都是待附加的
元素。因为mySlice中的元素类型为int,所以直接传递mySlice2是行不通的。加上省略号相
当于把mySlice2包含的所有元素打散后传入。
上述调用等同于:
mySlice = append(mySlice, 8, 9, 10)
数组切片会自动处理存储空间不足的问题。如果追加的内容长度超过当前已分配的存储空间
(即cap()调用返回的信息),数组切片会自动分配一块足够大的内存。

slice内容复制:copy(dstSlice, resSlice)

slice1 := []int{1, 2, 3, 4, 5}
slice2 := []
int{5, 4, 3}
copy(slice2, slice1) //只会复制slice1的前3个元素到slice2
copy(slice1, slice2) //只会复制slice23个元素到slice1的前3个位置

◆ 字典map

==========================================================================

package main

import "fmt"

 

// PersonInfo是一个包含个人详细信息的类型
type PersonInfostruct{
ID
string
Name string
Address string
}

 

func main(){

    var personDB map[string] PersonInfo

        personDB = make(map[string] PersonInfo)

 

        personDB["12345"] = PersonInfo{"12345", "Tom", "Room 202, ..."}

        personDB["1"] = PersonInfo{"1", "Jason", "Room 101, ..." }

 

        person, ok := personDB["1234"]

        if ok{

                fmt.Println("Found person", person.Name, "with ID 1234.");

        } else {

            fmt.Println("Did not find person whit ID 1234.")

        }

}

 

==========================================================================

 

var myMap map[string] PersonInfo

myMap = make(map[string] PersonInfo)

 

myMap := make(map[string] PersonInfo)

myMap := make(map[string] PersonInfo, 100)      //预留100PersonInfo空间

 

delete(myMap, "1234")

delete(myMap, nil) ==>编译器报错

 

◆ 通道 chan

◆ 结构体struct

◆ 接口interface

 

go变量与常量

◆ 变量

var v1 int = 10

var v2 = 10

v3 := 10

 

var i int              var i int

i := 2     ==>编译器报错   i = 2  ==>正确

 

i, j = j, i     //多重赋值 ==> C++: t = i; i = j; j = t;

_, _, nickName := GetName()     //匿名变量 "_"

 

◆ 常量

字面常量:无类型的,只要在值域范围内,就可以作为该类型常量

-12         //整型常量,-12可以赋值给intuintint32/64float32/64complex64/128

3.14            //浮点型常量

3.2+12i     //复数型常量

true            //布尔型常量

"str"       //字符串常量

 

常量定义:const关键字

const Pi float64 = 3.14159265358979

const (

    size int64 = 1024

    eof = -1

)

 

预定义常量:true、false、iota

iota比较特殊,可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被
重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1
从以下的例子可以基本理解iota的用法:
const (      // iota被重设为0
c0 = iota      // c0 == 0
c1 =
iota        // c1 == 1
c2 =
iota                   // c2 == 2
)
const (
a = 1 <<
iota         // a == 1 (iota在每个const开头被重设为0)
b = 1 <<
iota         // b == 2
c = 1 <<
iota         // c == 4
)

 

const (
   
Sunday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    numberOfDays // 这个常量没有导出
)

go流程控制

◆ if

===================================================================================

if a > 0 {

}

if i :=0; i < 0{

}

func exfunc(x int) int{

    if x == 0 {

        return 5    ==>编译器报错

    } else {

        return x       ==>编译器报错,不允许在函数体内的“if等”语句体内使用return

    }

}

===================================================================================

◆ switch : case 不支持break

◆ for : 不支持逗号多重赋值,支持continue、break控制循环

===================================================================================

for j := 0; j < 5; j++{

    for i := 0; i < 10; i++{

        if i > 5{

        break JLoop

        }

    }

}

JLoop: ...

===================================================================================

===================================================================================

for i := 0; i < len(arr); i++{

    ...

}

for i, v := range arr{

    ...

}

===================================================================================

===================================================================================

for i := 0; i < len(mySlice); i++{

    ...

}

 

for i, v := range myslice{

    ...

}

===================================================================================

===================================================================================

func myfunc(args ...int){//...type格式类型(syntactic sugar),只作为函参存在,且是最后一个参数

    for _, arg := range args{

        fmt.Println(arg)

    }

}==>myfunc(2,3,4);myfunc(4,5,6,4,65)

===================================================================================

◆ goto

func myfunc(){

    i := 0

    HERE:

    fmt.Println(i)

    i++

    if i < 10 {

        goto HERE

    }

}

go函数

◆ 函数定义

 

◆ 函数调用

 

◆ 不定参数

===================================================================================

func myfunc(args ...int){       //接受不定数量的参数,全部为int

    for _, arg := range args{

        fmt.Println(arg)

    }

}==>myfunc(2,3,4);myfunc(4,5,6,4,65)

//...type格式类型,本质是一个slice, []type

 

func myfunc(args ...int){

    myfunc3(args ...)

    myfunc3(args[1:] ...) int

}

 

fmt.Printf()的函数原型

func Printf(format string, args ... interface{}){   //interface{}传递任意类型数据

    ...

}

◆ 多返回值

◆ 匿名和闭包

 

go错误处理

◆ defer

◆ recover

◆ panic

◆ error

 

 

6g, 6l  ==>  6go, 6link  64位,编译,link

8g, 8l  ==>  8go, 8link  32位,编译,link

gccgo

>7.1 version GDB  ==> gdb calc   DWARFv3

版权声明:本文为博主原创文章,未经博主允许不得转载。

golang

标签:golang   goroutine   高并发   函数多返回值   多重赋值   

原文地址:http://blog.csdn.net/itcombox/article/details/48035117

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!