golang语法学习(一):变量,常量以及数据类型

  1. 云栖社区>
  2. 博客>
  3. 正文

golang语法学习(一):变量,常量以及数据类型

技术mix呢 2017-10-12 20:50:00 浏览1276
展开阅读全文

学习一门新的语言肯定是要从他的主要的语法開始,语法构成了整个程序设计的基础,从语法中我们也能够看到这门语言的一些特性。可是话说回来。语法这东西,不同的语言大同小异,所以这也对语法的记忆造成了一定的难度。事实上最好的方法应该是旁边有本书。随时能够拿过来查阅或者纠正。当然golang的语法也是这样,以下的一些是我学习七牛云存储团队许式伟等出的《Go语言编程》: 
http://baike.baidu.com/link?

url=vFrjnVJwITN0LaRbL7TmWYpq5V8JLWzL_NycAQy6w0e7JXP6a4bGm61ge0gGMU6jNFQO_RnuDGEQPh7YK9w4S_ 
语法部分的时候整理的一些,这本书对于新手入门还是挺有帮助的。为了日后能够及时回想。所以记录下来了。

为了避免长博客带来的阅读疲劳。这里尽量精简内容和分段。 
本文主要包含: 
1. Go中变量的声明,定义,赋值的方式以及匿名变量的概念。 
2. Go中常量的定义和使用 
3. Go中支持的内置数据类型及使用方法 
主要就是这三部分,整体来说介绍了这么语言中最主要的元素,就像构成英文的26个英文字母一样。

1. Go中的变量


1.1 变量声明


在Go中变量的声明方式例如以下:

var 变量名 变量类型

当中var是一个go内置的关键字,用来进行“纯粹“的变量的声明,注意这里的纯粹的意思。它是有别于系统依据赋值时候的右值进行自己主动推断变量类型的一种方式,能够觉得是定义一个绝对类型的变量。 
比方:

 var    v1    int    //定义一个整形v1
 var    v2    [10]int   //定义一个整形数组v2
 var    v3    struct  {          //定义了一个结构体
    ...
    f int 
    ...
}

等等。所以习惯了c,c++,java等语言定义变量的同学还须要特殊记忆一下这个定义方式。不知道go为什么这样定义,我推測可能是发明者之前使用的某种语言的习惯吧。可是我不知道是哪种,知道的读者也能够告诉我。

(后来发现这里也许能够解释 为什么golang的语法是这样的: 
http://blog.golang.org/gos-declaration-syntax)还有就是不是必需书写一条语句的分号了,当然加了也不会报错。 
同一时候为了避免反复书写var,也能够将多个变量定义在一起:

var {
    v1  int
    v2  string
}

1.2 变量的赋值。初始化

Go中变量的赋值非常easy。就是在定义完一个变量后。对变量赋初始值。没有什么特殊的地方。比方:

var i int
i = 10   //定义之后对i赋初值

可是在go中有一个非常大的改革就是,同意多重赋值,以往在c语言中,假设想对i,j两个变量赋值,须要两个等号,比如i=3, j=4;可是在go中能够直接写成:

i , j = 3, 4

非常easy。假设你想交换i,j的值,也仅仅须要写成:

i , j = j, i  //这就是go创新的地方

变量的初始化和变量的赋值相似。仅仅是在变量声明的时候直接给出赋值,在golang中支持三种初始化的方式:

var 变量 变量类型 = 初值 
var 变量 = 初值 
变量 := 初值 
比如以下:

var v1 int = 10  //最规矩的写法
var v2 = 10 //编译器自己主动推算v2类型
v3 := 10    //同一时候进行变量的声明和初始化工作

要特别注意”:=”这个在c,c++,java中都未曾出现过的符号,他能够缩短代码的行数。编译器应该是将这句话解释成为两句,var v3 int , v3 = 10 
所以”:=”的左側要是一个没有被声明过的变量,否则会以下的错误, 要特别注意

no new variables on left side of :=

1.3 Golang中匿名变量的概念

用过matlab这样的解释语言的读者应该对一个函数的多返回值有印象。在c,c++中假设要想返回多个值,要么是返回一个类型,结构体,或者在形參中传入要返回变量类型的指针。

这些在golang中直接支持了函数多返回值这样一种方式。可是。假设多返回值中有些是我们不须要的那么怎么办,和matlab相似。这里引入了匿名变量。”_”,事实上就是作为一种缺省。比如书中的列子:

func GetName() (firstName, lastName, nickName string) {
    return "may", "chan", "haha"
}
_, _ ,nickname := GetNmae() //这里面就是一种缺省。值用来获得nickName

2. Go中的常量

Go中也是用const来进行常量的定义,比如

const str string = "hellotest” //string类型
const  number int32 = 1234  //32位整形常量等
const (  //枚举类型,降低const的书写
    zero = 0.0
    eof = -1
)

除此之外,还有提前定义的变量,包含bool型”true”,”false”等以及自己主动增长的iota。


当中iota在出现const的时候被置0。之后没出现一次iota自己主动加1,直到被又一次置0为止。

比如

const (                     //iota被重设为0
        a = iota            //a = 0
        b = iota            //b=1
        c = iota            //c=2
) 

注意上面由于是枚举,能够简化为

const (                     //iota被重设为0
        a = iota            //a = 0
        b                   //b=1
        c                   //c=2
) 

1.3 Go支持的类型

先来看看Go支持的基础类型。然后我们环绕一些类型来介绍go中首创的,新奇的一些特性。 
和其它类型一样。go支持:

布尔型 bool 
整形 int8, byte, int16, int, uint, uintptr 
浮点类型: float32 (c中的float ), float64 ( c中的double ) 
复数类型: complex64, complex128(go中特有的) 
字符串: string (内置类型) 
字符类型: rune(Unicode字符类型), byte(UTF-8字符类型) 
错误类型: error 
以及复合类型: 
指针: pointer 数组: array 切片: alice 
字典: map 通道: chan 结构体: struct 接口: interface 
等 
以下我们分别介绍一下这些类型的使用注意事项:

1) bool类型。

在bool类型中。不像c中那样,对一个bool类型的变量仅仅能赋值,true或者false。

或者是比較运算。不能直接赋值0,1,也不能对0,1进行强制类型转换,比如

var v1 bool = true//正确
var b bool = (1==2) // 正确
var f1 bool = 1 // false
var f2 bool = bool(1) //错误

2) 整形

在整形中,go分别支持8,16,32,64bit的有符号和无符号整形。

当中 unit8 就是byte,相似于c语言中的char型。还有就是int和int32在go语言里是两种不同的类型,所以这两种类型的变量也不能够相互赋值以及进行运算。假设进行运算的话须要进行强制类型转换。同一时候go中的整形与C语言相似,也支持数值运算,比較运算。以及位运算。

除了位运算中的取反是使用^x 以外,C语言是使用~x,其它和C语言全然一样。

3) 浮点型

在浮点型中,go中定义了float32, float64两种,当中float32等价于C中的float,float64等价于C语言中的double。同一时候。在Go中,定义一个浮点数变量的时候,假设没有显示声明类型,编译器在自己主动推算的时候会将变量声明为float64而不是float32。比如:

fvalue := 12.0   //这里fvalue有编译器自己主动识别为float64

还有就是,浮点数中的推断相等比較的时候,由于浮点数的精度问题,所以不能直接用“==”来进行两个变量的推断。在math库中提供了。math.Fdim(var1,var2)来对两个变量的差值进行推断。

4) 复数类型

复数类型是go中引入的一种新的内置的数据类型。当中complex64表示用实部和虚由float32构成,complex128类推。复数的能够有以下3中使用方法:

var value1 complex64 = 3.2 + 12i
value2 := 3.2 + 12i
value3  := complex(3.2, 12)
 r = real(value1)       //获得复数的实部
 i  = imag(value1)    //获得复数的虚部

5) 字符串和字符类型

在go中,字符串是一种内置的类型,和C++中的包相似,能够使用数组下标的形式获取字符。可是注意,不能用这样的方式对字符进行改动。比如以下的使用方法:

var str string           //声明一个string类型的变量
str = "String Test"     //赋值
ch := str[0]           //获取第一个元素的值
length = len(str)     //字符串的长度
str[0] = 's'         //出错XXXX。

不能这样来赋值 str = str + "Haha" // 字符串的链接

在这里还须要注意的是,golang中仅仅支持UTF-8以及Unicode的编码。而对于其它的编码并没有内置的编码转换,所以在我们保存的时候须要非常小心。尤其是中国地区可能默认的保存的编码方式是GBK,这里提供七牛云存储团队自己搞的一个转换的源代码: https://github.com/xushiwei/go-iconv 
关于UTF-8的编码是用byte这样的类型来定义的。Unicode是用rune来定义的。所以要注意字符的编码方式,尤其是在字符串遍历的时候,假设使用range关键字。那么使用的是rune的形式来遍历的。而以数组取值的方式是byte的形式。

6)数组与数组切片

golang中的数组和c语言中的数组在一定程度上是一样的,包含元素的訪问等,都是从0到len-1; 
可是golang中的数组有几个新的特性。包含: 
a. 能够使用len获得数组的长度 
b. 能够使用range来遍历訪问容器中的元素。相似于foreach.比如

for i, v := range array { 
    fmt.Println("Array element ['', i , '']=", v)
}  //两个返回值

c. golang中的数组是值类型,和c语言中的数组名代表的是首地址不同。所以在传递数组的时候,不会改变原数组中的值,而且由于是值传递。所以每次都会进行一次形參值得copy。而这明显降低了函数调用的效率和空间的浪费。所以在golang中还提供了数组切片的功能。


数组切片(slice)能够觉得是关联某个数组的一个数据结构,这个数据结构包含以下三部分:

其所关联的数组的指针; 
数组切片中数组的元素的个数。(即实际包含的数组元素的个数) 
数组切片分配了的存储空间。(含有多大的空间) 
以下是创建数组切片的三种方式:

/*
one way:基于原生数组创建
*/
var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}  
var mySlice [ ]int = myArray[:5]  
/*
second way: 使用make直接创建
*/
mySlice1 := make([ ]int,5)  //出事元素个数是5,且都为0
mySlice2 := make([ ]int, 5, 10)  //容量是10
mySlice3 := [ ]int{1,2,3,4,5}  //元素是1,2,3,4,5的切片。

/* third way: 基于已有的切片进行创建 */ oldSlice := []int{1, 2, 3, 4, 5} newSlice := oldSlice[:3] // 基于oldSlice的前3个元素构建新数组切片

对数组切片的操作: 
append函数用来附加;copy函数用来进行复制。

mySlice2 := []int{8, 9, 10} // 给mySlice后面加入还有一个数组切片
mySlice = append(mySlice, mySlice2...)//注意mySlice2后面的...不能省
//等价于:
mySlice = append(mySlice,8,9,10)

7)map

map是golang中内置的一种数据类型,与C++ STL中的map不同的是,这里的map没有依照键值对排序。(不知道为什么要这样,知道的读者也能够告诉我为什么不排序。那样的话查找不是非常慢吗?可能插入删除会快些,这里面是个trade off?


map的使用包含例如以下几个方面:

a. 声明和创建,使用map,make关键词 
var map变量名 map[key的类型] value的类型 = make (map[key的类型] value的类型,元素容量) 当中元素容量參数可省。 
比如: 
var myMap map[string] PersonInfo = make (map[string] PersonInfo,100)

b. 初始化和赋值 
能够在创建map变量的时候直接初始化, 
myMap = map[string] PersonInfo { 
“1234”: PersonInfo{“1”, “Jack”, “Room 101, …”}, 

或者直接给key赋值: 
myMap[“1234”] = PersonInfo{“1”, “Jack”, “Room 101, …”}

c. 元素的删除 
直接使用delete(map容器,key值)函数,删除容器内的元素。

比如:delete(myMap, “1234”);

d. 元素的查找 
golang中的map查找直接通过数组訪问的形式。比如: 
value, ok := myMap[“1234”] 
if ok { // 找到了 
// 处理找到的value 

能够看到,返回值是两个,当中value是待查找的元素的key存在情况下的值,ok表示是否找到。

所以这里的查找能够节省之前STL中使用find的一些逻辑较多的代码。

总结

到此为止。学了golang中最主要的组成语言的元素,包含变量,常量,以及支持的类型等。 
以下我们将要学习golang语法中的语句组织形式,函数等。




本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5183187.html,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术mix呢
+ 关注