## 4.6\. 类型简介
Go语言中有一些通用的类型,例如"int"和"float",它们对应的内存大小和处理器类型相关。同时, 也包含了许多固定大小的类型,例如"int8"和"float64",还有无符号类型"uint"和"uint32"等。 需要注意的是,即使"int"和"int32"占有同样的内存大小,但并不是同一种数据类型。不过 "byte"和"uint8"对应是相同的数据类型,它们是字符串中字符类型。
go中的字符串是一个内建数据类型。字符串虽然是字符序列,但并不是一个字符数组。可以创建新的 字符串,但是不能改变字符串。不过我们可以通过新的字符串来达到想改变字符串的目的。 下面列举"strings.go"例子说明字符串的常见用法:
```
11 s := "hello"
12 if s[1] != 'e' { os.Exit(1) }
13 s = "good bye"
14 var p *string = &s
15 *p = "ciao"
```
不管如何,试图修改字符串的做法都是被禁止的:
```
s[0] = 'x';
(*p)[1] = 'y';
```
Go中的字符串和C++中的"const strings"概念类似,字符串指针则相当于C++中的"const strings" 引用。
是的,它们都是指针,但是Go中用法更简单一些。
数组的声明如下:
```
var arrayOfInt [10]int;
```
数组和字符串一样也是一个值对象,不过数组的元素是可以修改的。不同于C语言的是:"int"类型数组 "arrayOfInt"并不能转化为"int"指针。因为,在Go语言中数组是一个值对象,它在内部保存"int"指针。
数组的大小是数组类型的一部分。我们还可以通过slice(切片)类型的变量来访问数组。 首先,数据元素的类型要和slice(切片)类型相同,然后通过"a: high?"类似的 语法来关联数组的low到heigh-1的子区间元素。Slices和数组的声明语法类似,但是不像数组那样 要指定元素的个数(""和"10?"的区别);它在内部引用特定的空间,或者其它数组的空间。 如果多个Slices引用同一个数组,则可以共享数组的空间。但是不同数组之间是无法共享内存空间的。
在Go语言中Slices比数组使用的更为普遍,因为它更有弹性,引用的语法也使得它效率很高。 但是,Slices缺少对内存的绝对控制比数组要差一些。例如你只是想要一个可以存放100个元素 的空间,那么你就可以选择数组了。创建数组:
```
[3]int{1,2,3}
```
上面的语句创建一个含有3个元素的int数组。
当需要传递一个数组给函数时,你应该将函数的参数定义为一个Slice。这样,在调用函数的时候, 数组将被自动转换为slice传入。
比如以下函数以slices类型为参数(来自"sum.go"):
```
09 func sum(a []int) int { // returns an int
10 s := 0
11 for i := 0; i < len(a); i++ {
12 s += a[i]
13 }
14 return s
15 }
```
函数的返回值类型(int)在sum()函数的参数列表后面定义。
为了调用sum函数,我们需要一个slice作为参数。我们先创建一个数组,然后将数组转为slice类型:
```
s := sum([3]int{1,2,3}[:])
```
如果你创建一个初始化的数组,你可以让编译器自动计算数组的元素数目,只要在数组大小中填写"..."就 可以了:
```
s := sum([...]int{1,2,3}[:])
```
是实际编码中,如果不关心内存的具体细节,可以用slice类型(省略数组的大小)来代替数组地址为函数参数:
```
s := sum([]int{1,2,3});
```
还有map类型,可以用以下代码初始化:
```
m := map[string]int{"one":1 , "two":2}
```
用内建的"len()"函数,可以获取map中元素的数目,该函数在前面的"sum"中用到过。"len()"函数 还可以用在strings, arrays, slices, maps, 和 channels 中。
还有另外的"range"语法可以用到strings, arrays, slices, maps, 和 channels 中, 它可以用于"for"循环的迭代。例如以下代码
```
for i := 0; i < len(a); i++ { ... }
```
用"range"语法可以写成:
```
for i, v := range a { ... }
```
这里的"i"对应元素的索引,"v"对应元素的值。关于更多的细节可以参考 Effective Go。
- 1. 关于本文
- 2. Go语言简介
- 3. 安装go环境
- 3.1. 简介
- 3.2. 安装C语言工具
- 3.3. 安装Mercurial
- 3.4. 获取代码
- 3.5. 安装Go
- 3.6. 编写程序
- 3.7. 进一步学习
- 3.8. 更新go到新版本
- 3.9. 社区资源
- 3.10. 环境变量
- 4. Go语言入门
- 4.1. 简介
- 4.2. Hello,世界
- 4.3. 分号(Semicolons)
- 4.4. 编译
- 4.5. Echo
- 4.6. 类型简介
- 4.7. 申请内存
- 4.8. 常量
- 4.9. I/O包
- 4.10. Rotting cats
- 4.11. Sorting
- 4.12. 打印输出
- 4.13. 生成素数
- 4.14. Multiplexing
- 5. Effective Go
- 5.1. 简介
- 5.2. 格式化
- 5.3. 注释
- 5.4. 命名
- 5.5. 分号
- 5.6. 控制流
- 5.7. 函数
- 5.8. 数据
- 5.9. 初始化
- 5.10. 方法
- 5.11. 接口和其他类型
- 5.12. 内置
- 5.13. 并发
- 5.14. 错误处理
- 5.15. Web服务器
- 6. 如何编写Go程序
- 6.1. 简介
- 6.2. 社区资源
- 6.3. 新建一个包
- 6.4. 测试
- 6.5. 一个带测试的演示包
- 7. Codelab: 编写Web程序
- 7.1. 简介
- 7.2. 开始
- 7.3. 数据结构
- 7.4. 使用http包
- 7.5. 基于http提供wiki页面
- 7.6. 编辑页面
- 7.7. template包
- 7.8. 处理不存在的页面
- 7.9. 储存页面
- 7.10. 错误处理
- 7.11. 模板缓存
- 7.12. 验证
- 7.13. 函数文本和闭包
- 7.14. 试试!
- 7.15. 其他任务
- 8. 针对C++程序员指南
- 8.1. 概念差异
- 8.2. 语法
- 8.3. 常量
- 8.4. Slices(切片)
- 8.5. 构造值对象
- 8.6. Interfaces(接口)
- 8.7. Goroutines
- 8.8. Channels(管道)
- 9. 内存模型
- 9.1. 简介
- 9.2. Happens Before
- 9.3. 同步(Synchronization)
- 9.4. 错误的同步方式
- 10. 附录
- 10.1. 命令行工具
- 10.2. 视频和讲座
- 10.3. Release History
- 10.4. Go Roadmap
- 10.5. 相关资源