许世伟的Go语言基础 第二章总结

第2章 顺序编程

2.1 变量

变量声明

变量声明的类型信息放在变量之后,放在数组的中括号之后,作返回值类型放在方法名之后。

不需要使用分号作为结束符。

//字串和哈希表都是内置类型,都小写

varv1int

varv2string

varv3[10]int

varv4[]int//数组切片

v4=make([]string,10)

varv5stuct{

fint

}

varv6*int

varv7map[string]int//map,key为string类型,value为int类型

varv8func(aint)int

Go语言是个静态类型语言,但以上写法看上去却像动态语言。

var只用来声明,直接不值不用写var。

varv1=1//编译器报错

go语言变量赋值不使用也报错。

变量初始化

注意类型推演符左侧的就是不应该是已被声明过的。

varv1int=10

varv2=10//不指明类型也可以变量推演

varv3:=10//使用类型推演符:=

==总结==:没声明的必须类型推演,只声明没指定类型的可以类型推演,已声明类型的不能类型推演。

不用类型推演:=,用变量必须声明var,可以不写类型。

交换2个变量的值直接用多重赋值

i,j=j,i

匿名变量

可以使用多重返回和匿名变量的写法,使代码更优雅。

funcmain() {

    _,_,nickName:=GetName()

}

//多个同样类型的变量只声明一次就可以

funcGetName() (firstName,lastName,nickNamestring)  {

    return"May","Chan","Maruko"

}

字面常量

Go语言的字面常量是无类型的,只要值在某类型的值域范围内,就可以赋值(不用再写类型转换了,简化代码)。如-12可以赋给int、unit、int32、float64等。

-12

3.14159//浮点型常量

3.2+12i//复数常量

true//布尔型常量

"foo"//字串常量

常量定义

常量也可以限定类型,但不是必须的。

constzerofloat64=3.14159

constzero=3.14159// 无类型常量

const{

zeroint64=0

zero=0//无类型常量

}

==常量赋值是编译期行为==,常量定义的右侧值也可以是一个编译期运行的常量表达式。

constmask=1<<3

//os.GetEnv("HOME")是运行期返回结果,所以下行代码编译错误

constHome=os.GetEnv("HOME")

预定义常量

go语言有3个预定义常量:true、false、iota。

每const关键字出现时,iota被重置为0,每出现一次iota其值增1。

const{

c0=iota

c1=iota

c2=iota

}

两个const赋值表达式是一样的,则可以省略后一个(==方便之处在于枚举型赋值,但可能带来意外赋值==)。这种写法多用于枚举型。

const{

a=1<

b//b == 2

c//c == 4

}

枚举

go语言并不支持enum关键字。枚举使用const后跟一对==圆括号==定义一组常量。

const(

Sunday=iota

Monay

TuesDay

numberOfDays//这个常量没有导出

)

go语言中大写字母的常量在包外可见,相当于访问限制符。

2.3 类型

go语言内置以下基础类型(7个)

bool

byte int unit int8 int16 uint uintptr等。(整形一般用int unit就可以了,以免移植困难)

float32 float64

complex64 complex128

string

字符类型rune

错误类型error

go语言的复合类型(7个)

指针pointer

数组array

切片slice

字典map

通道chan

结构体struct

接口interface

布尔型

varv1bool=true

布尔型不接受其它类型的赋值,也不支持强制类型转换。

整形

int和int32是两种不同的类型,编译器不会自动转换。

value1:=64//自动推导为

varvalue2int32

value2=value1//编译器报错

go语言不会隐式的类型转换,不同类型的整型不能比较和赋值,如int8和int。但可以直接与字面值常量比较(无类型)。(没有隐式类型转换的烦恼)

不同类型赋值要强制类型转换

value2=int32(value1)//强制转换用静态方法

variint32

varjint64

i,j=1,2

ifi==j{}//编译器报错

ifi==1||j==2{}//编译通过

==取反运算符是^x==,这与C语言不同。

浮点型

varfvalue1

fvalue1:=12.0//加小数点,推导为浮点型。

float32等价于C语言中的float型,float64等价于C语言中的double型(浮点型自动推演的的类型)。

用==比较浮点型不稳定,使用以下方案:

import"math"

funcIsEqual(f1,f2,pfloat64){

returnmath.Fdim(f1,f2)

}

复数

复数表示

varvaluecomplex64

value1=3.2+12i

value2:=complex(3.2,12)

real(value1)//取实部

imag(value1)//取虚部

字串

varstrstring

str="hello"

ch:=str[0]

fmt.Printf("the length of \"%s\" is %d \n",str,len(str))

fmt.Printf("the first character of \"%s\" is %c"str,ch)

字串不能在初始化后修改

str:="hello"

str[0]"X"//编译错误

字串编码转换go只支持utf-8和unicode。其它可用iconv库转换。

字串操作:

x+y//字串连接

len(s)//取字串长度

s[i]//取字符

//两种字串遍历方式

str:="hello"

n:=len(str)

fori,ch:=rangestr{

fmt.Println(i,ch)

}

fori:=0;i

ch:=str[i]

fmt.Println(i,ch)//可以直接打印两个字符

}

字符

两种字符类型,byte表示UTF-8字串的单个字节值,rune代表单个Unicode字符。

数组

数组声明方法:

[32]byte

[2*N]struct{x,yint}//复杂类型数组

[1000]*float指针类型数组

[3][5]int//二维数组

[2][2][2]float64//等同于[2]([2]([2]float64))

varfVar[2][2]float64=[2][2]float64{{1,2},{1,2}}

数组可以是多维的,一旦定义长度后就不能修改。

go语言是值类型,在赋值和参数传递时会进行一次复制动作。因而在函数体中无法修改数组的内容,函数内操作的只是所传入数组的一个副本。

数组切片

数组在长度定义后无法修改,数组是值类型,这些无法满足开发者需求。

数组切片的数据结构可以抽象为以下3个变量:(类似于ArrayList)

指向原生数组的指针

数组切片的元素个数

数组切片已分配的存储空间

vararray1[10]int=[10]int{1,2,3,4,5,6,7,8,9,10}

varslice1[]int=array1[:5]//使用数组的片段创建切片

slice2=make([]int,5)//创建元素个数为5的数组切片

slice3=make([]int,10)//创建元素个数5的数组切片,预留10个存储空间

slice4:=[]int{1,2,3,4,5}//直接创建5个元素的数组切片

len(slice1)

cap(slice1)//返回容量大小

这里书中有误:==make方法返回值==赋变量 ,无需类型推演。

==让编译器自行统计元素个数==:

b := [...]string{"Penn", "Teller"}

切片能够区分元素个数和容量。为避免扩容开销,容量由开发人员指定。

slice1:=append(slice1,8,9,10)//向切片末尾添加元素

slice1:=append(slice1,slice2)//添加切片

使用切片创建切片:

newSlice:=oldSlice[:3]//选择范围超过原切片,则补上0

切片复制:

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

slice2:=[]int(5,4,3)

copy(slice2,slice1)//只复制slice1的前3个元素到slice2中

copy(slice1,slice2)//复制slice2的元素到slice1的前3个位置

切片复制的原则是==不改变原切片长度==。

map

varmap1map[int]string

map1=make(map[int]string)

map1[1]="jack"

map1[2]="bill"

str,ok=map1[1]//查找键为1的数据

map的多返回值判断是否查找成功,使代码更简洁。

map初始化时可以设置容量:

map1=make(map[int]string,100)

添加元素如同元素赋值。

删除元素:

delete(map1,1)

struct(引自博客)

//结构体初始化

b := person{

       name: "wyff",

       age:  300,

   }

2.4 流程控制

选择语句支持switch、case和select。循环语句支持for和rage。跳转语句支持goto。

if语句要求

不需要括号()包条件

无论几条语句,{}是必须的

左花括号必须与if/else在同一行

有返回值函数中,不允许将"最终"return放在if...else中。

if语句也可以在条件表达式前加赋值语句。

switch选择语句

    switchi{

    case0:

        fmt.Print("0")

    case1:

        fmt.Print("1")

    case2:

        fmt.Print("2")

    default:

        fmt.Print("default")

    }

switch后无表达式的写法:

    varNum

    switch{

    case0

        fmt.Print("0-3")

    case4

        fmt.Print("4-6")

    }

//case不再是匹配项,而是表达式。

要求:

左花括号必须与switch处于同一行

条件表达式==不限制不整形或常量==,也可以不写

单个case可以出现多结果选项??

==不需要break来明确退出一个case==,只有加fallthrough关键字才继续执行下一个case。

switch后无表达式,与if...else逻辑等同。

循环语句

无限循还直接写,而不需要for(;;)和do{}while(1)

for{


}

条件表达式支持多重赋值:

foti,j=0,len(arr);i

a[i],a[j]=a[j],a[i]

}

支持continue break循环控制,还可以决定跳出哪个循还。

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

fori:=0;i<5;i++{

ifi>3{

breakJLoop

   }

fmt.

  }

}

JLoop://循环标签

==注意循还标签有冒号==。Java使用bool标志来实现。

跳转语句

HERE:

ifi<10{

gotoHERE

}

2.5 函数

相邻的类型相同的参数,可以只写一个类型声明

函数的返回值的变量需要命名,只有一个可以不命名

funcAdd(a,bint)(resint,errerror){

err=errors.New("have errors")

return

}

forAdd(a,bint)int{}//单个返回值

func(a*Integer)Add(i,jint)int{returnx+y}//类方法的写法,是否加*后面讲

函数和变量的小写仅在包内可见,大写才能被其它包使用。相当于访问限制符。

多返回值

匿名函数和闭包

匿名函数可以直接赋值给一个变量或直接执行。

f:=func(x,yint)int{

returnx+y

}

f:=func(x,yint)int{

returnx+y

}(1,2)//后面带参数表示直接执行

匿名函数是一个闭包。

闭包定义:包含自由变量(未绑定到对象)的代码块。要执行的代码块为自由变量提供绑定的计算环境(作用域)。

闭包的价值:用作函数对象或匿名函数,==支持闭包的语言将函数存储到变量作为参数传递给其它函数==。

闭包是函数式编程中很重要的概念。

funcmain() {

    varjint=5

    a:=func() (func()){

        variint=10

        returnfunc() {fmt.Printf("i,j:%d,%d",i,j)}

    }()

    a()

    j*=2

    a()

}

//闭包内的i值被隔离,不会被修改。

//fmt.Print()用法如java,fmt.Printf()用法如C。

错误处理

typeerrorinterface{

Error()string

}

将error作为多返回值的最后一个,用于函数的返回错误。

错误处理:

iferr!=nil{}

defer关键字

提前写关闭文件、连接的语句。java用finally,C++用包一个类在析构函数中关闭。

funcCopyFile(dst,srcstring) (wint64,errerror) {

    srcFile,err:=os.Open(src)

    iferr!=nil{

        return

    }

    defersrcFile.Close()

    dstFile,err:=os.Create(dst)

    iferr!=nil{

        return

    }

    deferdstFile.Close()

    returnio.Copy(dstFile,srcFile)

}

panic()和recover()方法

错误处理流程:

当一个函数调用panic()函数时,正常的函数执行流程立即终止。

但使用defer关键字推迟执行语句正常展开执行。

函数返回到调用函数,逐层执行panic流程,直至所属的goroutine中所有执行的函数被终止。

报告错误信息,包括panic()函数传入的参数。

panic()的形参接收任意类型的数据。

recover()函数终止错误处理流程:如果没有在没有发生异常的goroutine中明确地调用恢复过程(使用recover()),则goroutine所属的进程==打印异常信息==后直接退出。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 出处---Go编程语言 欢迎来到 Go 编程语言指南。本指南涵盖了该语言的大部分重要特性 Go 语言的交互式简介,...
    Tuberose阅读 18,396评论 1 46
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,422评论 3 44
  • 1.安装 https://studygolang.com/dl 2.使用vscode编辑器安装go插件 3.go语...
    go含羞草阅读 1,538评论 0 6
  • 每个家长对于孩子的培养都有着自己的预期:有的希望孩子成为学霸,有的希望孩子成为艺术家,有的希望孩子成为运动健将……...
    熊孩子他爹LEO叔阅读 223评论 0 0
  • 本篇目的: 为什么要安装ubuntu 如何安装buntu系统 为什么要安装ubuntu? 在linxu中开发c/c...