Go语言中变量的声明和JavaScript非常相似。使用var关键字,变量声明和定义有几种形式1.变量和常量//声明和初始化一个变量varmint=10//声明和初始化多个变量vari,j,k=1,2,3//多个变量的声明(注意括号的使用)var(nointnamestring)//声明时没有指定类型,通过初始化值推导varb=true//bool类型//:=隐式声明一个变量并赋值str:="mimvp.com"//等价于varstrstring="mimvp.com"Go=和:=在语言上有什么区别?=是赋值,:=是声明变量并赋值//=必须先使用var声明例如:varaa=100//orvarb=100//orvarcint=100//:=是一个声明和赋值,系统自动推断类型,不需要var关键字d:=100//Go中有一个特殊的变量下划线“_”,这意味着赋给它的任何值都会被丢弃_,ret:=2,3//2assignment被废弃的Go语言的编译器对于已声明但未使用的变量报错,所以变量必须在声明后使用。如果要使用变量,必须先声明Go语言。和C语言一样,Go语言也使用分号来结束。陈述。但与C语言不同的是,Go语言的词法分析器在扫描源码的过程中,使用简单的规则自动插入分号,因此在编写源码时无需添加分号。Go语言词法分析器插入分号的规则:如果换行前的最后一个token是一个标识符(包括int和float64这样的词),一个像value这样的原始字面量,或者是下面的其中一个token,则自动插入分号Go一般仅在for语句中使用分号来分隔初始值设定项、添加项和增量项。另一种情况是在一行中写多条语句时,也需要用分号隔开。由于Go语言词法分析器添加分号的特殊性,在某些情况下需要注意:不应该把一个控制结构(if、for、switch、select)的左大括号放在下一个线。这样做会在花括号前插入一个分号,这可能会导致不需要的结果。常量:程序中不能改变的值,一般定义为数值、布尔值、字符串等。格式:constconstName[type]=val1)。varnum=3//其实3也叫常量2)。在格式中,val可以是一个表达式,但不能是一个结果只能在运行时才知道的表达式3)。预定义常量:true/false/iota4)。定义多个常量时,也可以使用如下方法const(constName1[type]=val1constName2[type]=val2)示例代码:/***mimvp.com*2017.1.20*///声明包名的当前文件,main是一个可以独立运行的包,编译后会生成一个可执行文件packagemainimport"fmt"//importpackagevarid=123456/*id2:=654321//在函数外使用:=,编译时会报错,局部变量声明要在函数内部//函数体外的非声明语句*/constPI=3.14//常量声明//每个能独立运行的程序都包含入口函数main,和其他语言一样,只是没有参数和返回值funcmain(){varnumintnum=100fmt.Println(num)//输出100varnum1,num2intnum1,num2=1,2fmt.Println(num1,num2)//输出12varno1,no2=3,4fmt.Println(no1,no2)//输出34n1,n2:=5,6fmt.Println(n1,n2)//输出56_,n:=7,8fmt.Println(n)//输出8var(key1stringkey2string)key1,key2="k1","k2"fmt.Println(key1,key2)//输出k1k2var(a=9b=10)fmt.Println(a,b)//输出910fmt.Println(id)//输出123456fmt.Println(PI)//输出3.14/*PI=3.1415//改变常量的值,编译错误//不能赋值给PI//不能使用3.1415(typefloat64)astypeidealinassignment*/}2.函数使用1)Go语言函数格式funcGetMsg(iint)(strstring){fmt.Println(i)str="hellomimvp.com"returnstr}解释:func表示这是一个函数GetMsg是函数名(iint)函数接收一个int型参数,为传入参数(strstring)函数返回一个string类型的返回值,为返回参数2)Go语言函数可以返回多个值函数返回多个值与Java、PHP、C等主流语言不同,与Python、lua等脚本语言相同。funcGetMsg(iint)(strstring,errstring){fmt.Println(i)str="hellomimvp.com"err="noerr"returnstr,err}funcmain(){fmt.Println(GetMsg(100))}编译执行:$gobuildmimvp_func.go$./mimvp_func100hellomimvp.comnoerr3)deferdef的使用er的意思是“函数退出时调用”,尤其是用来读写文件时,需要在open之后调用close操作,将close操作用到deferfuncReadFile(filePathstring)(){file.Open(filePath)deferfile.Close()iftrue{file.Read()}else{returnfalse}}上面代码的意思是,file.Open后并没有立即调用close,file.Close()是return为false时调用,有效避免了C语言中的内存泄漏问题4)理解恐慌和恢复。上面介绍了很多变量和函数,throw-try-catch的用法还没有介绍。Go语言中Panic和Recover是throw和catch,其他语言的示例代码:func(){如果r:=recover();r!=nil{fmt.Println("在f中恢复",r)}}()fmt.Println("调用g.")g(0)fmt.Println("从g正常返回。")}funcg(iint){ifi>3{fmt.Println("Panicking!")panic(fmt.Sprintf("%v",i))}deferfmt.Println("Defering",i)fmt.Println("Printinging",i)g(i+1)}运行结果:$./mimvp-try-catchCallingg.Printinging0Printinging1Printinging2Printinging3Panicking!Defering3Defering2Defering1Defering0Recoveredinf4f正常返回.Panic抛出一个消息并退出函数。恢复接收信息并继续处理。这个例子解释了基本就掌握了Recover和Panic3。Socks5代理服务器packagemainimport("net""fmt""io""bytes""encoding/binary")typeMethodsstruct{ver,nmethodsuint8methodsuint8}typesock5cmdstruct{ver,cmd,rsv,atypuint8dst[255]uint8}typeproxyCoderstruct{connnet.Conn}func(c*proxyCoder)readMethods()方法{varm方法b:=make([]byte,1024)n,err:=c.conn.Read(b)iferr!=nil&&err!=io.EOF{panic(err)}buf:=bytes.NewBuffer(b[0:n])err=binary.Read(buf,binary.LittleEndian,&m.ver)如果err!=nil{fmt.Println("binary.Readfailed:",err)}err=binary.Read(buf,binary.LittleEndian,&m.nmethods)iferr!=nil{fmt.Println("binary.Readfailed:",err)}err=binary.Read(buf,binary.BigEndian,&m.methods)如果err!=nil{fmt.Println("binary.Readfailed:",err)}returnm}func(c*proxyCoder)returnMethod(){buf:=make([]byte,2)buf[0]=5buf[1]=0c.conn.Write(buf)fmt.Println(buf)}func(c*proxyCoder)serve(){buf:=make([]byte,128)n,err:=c.conn.Read(buf)iferr!=nil&&err!=io.EOF{panic(err)}fmt.Println(buf[:n])varsstringvartstringvariintif(buf[3]==3){//domailfori=4;我
