go - 复合类型 array, slice, map
Go 语言支持复合类型:
- 数组:array
- 切片:slice
- 指针:pointer
- 字典:map
- 通道:chan
- 结构体:struct
- 接口:interface
1. array
同一类型数据的集合
var arr [n]type //声明type类型一维数组
var arr [m][n]type //声明type类型二维数组
多维数组以此类推
也可以用 := 声明
arr := [n]type{元素1[,元素2, ...]} 其中n可以用 "..." 三个点表示,系统会根据元素个数来确定
下标只能为 int 类型,而 php 还支持 string 类型的下标
1.1 数组长度 len(arr)
注:数组长度在定义后就不可变
1.2 遍历:
a. 循环通过过数组下标访问 arr[0] ~ arr[(len(arr))]
b. range arr, 有两个返回值 第一个为数组下标,第二个为元素的值,与php遍历数组相似
- for k, v := range array {
- fmt.Printf("arr[%d] = %d \t", k, v)
- }
- foreach ($arr as $k => $v) {
- printf("arr[%d] = %d \t", $k, $v);
- //echo '$arr[' . $k . "] = " . $v . "\t";
- }
1.3 数组在赋值与传递参数时,都会产生一个数组副本,而不是使用它的指针
2. slice
在定义 array 时,其长度是固定的,并且 array 是一个值类型
而 slice 是一个可变的数组,但是一个引用类型
2.1 产生slice的三种方式
a. 声明与 array 一样,不过不需要指定长度
var slice1 []int
slice2 := []int {元素1[, 元素2, ...]}
b. 从数组(或者切片或者字符串)中获取 arr[i:j] i=数组的开始位置,j=结束位结果,j-i=切片的长度,i和j都可以省略,省略时 i=0, j=len(arr),i是从0开始,j是从1开始
a b c d e f
i 0 1 2 3 4 5
j 1 2 3 4 5 6
- slice1 := arr[:] //arr[0:6]/arr[0:]
- slice2 := arr[1:1] //[]
- slice4 := arr3[1:3] //b c
- slice5 := arr3[:5] // = arr3[0:5]
c. make
slice1 := make([]int, 5, 10)
len(slice1) = 5, cap(slice1) = 10, 元素的初始值为0
2.2 相关函数
len(slice): 返回 slice 的元素个数(长度)
cap(slice): 返回 slice 的分配空间大小
append(slice1, slice2...): 把 slice2 追加到 slice1 产生新的 slice, 若 slice2 是变量时,不能省略...,相当于 append(slice1, a[, b, ...])
copy(目标slice, 源slice): 以最小的切片元素个数为准,将源 slice 复制到 目标 slice
2.3 cap - len = 0 时,系统将动态分配新的数组空间,即切片会自动处理存储空间不足的问题
2.4 遍历与 array 一样
2.5 在传递参数时,传递的为指针
3. map
在Java/python等语言中都有提供
暂时可以理解为:一张无序的表
其长度也不固定,也是引用类型,在赋值与传参过程中,指向同一地址
key1 value1
key2 value2
... ...
3.1 声明与创建
var map变量名 map[键type] 值type //键type可以为int或者string,值type,需要make初始化
map变量名 = make(map[键type] 值type)
//或者
map变量名 := make(map[键type] 值type) [{键1:值1}[,{键2:值2},...}] //[]中为可选
3.2 相关操作
赋值: map变量名[键] = 值
读取: map变量名[键] //如果键不存在,返回nil
删除键值对: delete(map变量名, 键) //如果键不存在,无影响
取map的元素个数: len(map变量名)
不能用cap函数
note_type_2.go code list
- package main
- import "fmt"
- func main() {
- //先声明后赋值
- var arr [3]int
- //arr = {1, 2, 3} //不能这样赋值给数组
- arr[0] = 1
- arr[1] = 2
- arr[2] = 3
- //arr[3] = 4 //compile error: index out of bounds
- fmt.Println(arr[0], arr[0:2]) //输出 1 [1 2]
- //arr1 := [3]int{4, 5, 6}
- arr1 := [...]int{4, 5, 6} //和上面结果一样
- fmt.Printf("arr[1] = %d \n", arr1[1]) //输出 arr[1] = 5
- //遍历数组
- for i := 0; i < len(arr); i++ {
- fmt.Printf("arr[%d] = %d \t", i, arr[i])
- }
- fmt.Println()
- for k, v := range arr1 {
- fmt.Printf("arr[%d] = %d \t", k, v)
- }
- fmt.Println()
- changeValue(arr1)
- fmt.Println("result: ", arr1) //result: [4 5 6] 值不发生改变
- //二维数组
- arr2 := [2][3]int{{1, 2}, {4, 5, 6}}
- fmt.Println("len(arr2) = ", len(arr2)) //len(arr2) = 2
- fmt.Println("len(arr2[0]) = ", len(arr2[0])) //len(arr2[0]) = 3
- for i, v := range arr2 {
- fmt.Println(i, v)
- }
- for i1, v1 := range arr2 {
- for i2, v2 := range v1 {
- fmt.Printf("arr2[%d][%d] = %d \t", i1, i2, v2)
- }
- fmt.Println()
- }
- //slice
- slice1 := []byte {'b', 'b'}
- slice1[0] = 'a' //如果只声明了slice,无元素时,直接通过下标赋值会compile error
- fmt.Printf("slice1[0] = %c \n", slice1[0]) //slice1[0] = a
- arr3 := [...]byte {'a', 'b', 'c', 'd', 'e', 'f'}
- slice2 := arr3[:] // = arr3[0:]
- fmt.Println("slice2 = ", slice2)
- slice3 := arr3[1:1] //空
- fmt.Println("slice3 = ", slice3)
- slice4 := arr3[1:3] //b c
- fmt.Println("slice4 = ", slice4)
- slice5 := arr3[:5] // = arr3[0:5]
- fmt.Println("slice5 = ", slice5)
- slice6 := slice5[1:2] //b
- fmt.Println("slice6 = ", slice6)
- str := "hello"
- slice7 := str[4:5] //o
- fmt.Printf("slice7[0] = %s \n", slice7) //slice7[0] = o
- fmt.Println("len(slice4) = ", len(slice4)) //len(slice4) = 2
- fmt.Println("cap(slice4) = ", cap(slice4)) //cap(slice4) = 5
- //slice8 := append(slice4, 'a', 'd') //b c a d
- slice9 := []byte {'a', 'b'}
- slice8 := append(slice4, slice9...) //b c a d = append(slice4, 'a', 'b')
- fmt.Printf("slice8[2] = %c \n", slice8[2]) //slice8[2] = a
- fmt.Println("len(slice8) = ", len(slice8)) //len(slice8) = 4
- slice10 := []byte {'x', 'y', 'z'}
- copy(slice10, slice9)
- for i, v := range slice10 {
- fmt.Printf("slice10[%d] = %c \t", i, v) //a b z
- }
- fmt.Println()
- /*
- //slice9 = a, b; slice10 = x, y,z
- copy(slice9, slice10)
- for i, v := range slice9 {
- fmt.Printf("slice9[%d] = %c \t", i, v) //x y
- }
- */
- s1 := make([]int, 5, 10)
- fmt.Println("len, cap = ", len(s1), ", ", cap(s1)) //len, cap = 5, 10
- s2 := []int {1, 2, 3}
- changeValue2(s2)
- fmt.Println("result2: ", s2) //result2: [5 2 3] 结果会发生改变
- //map
- var map1 map[string] string
- //map1["a"] = "123" //如果不初始化,会出现异常 panic: runtime error: assignment to entry in nil map
- map1 = make(map[string] string)
- map1["a"] = "123"
- fmt.Println("map1 = ", map1) //map1 = map[a:123]
- fmt.Println(map1["b"]) // (nil)
- b, found := map1["b"] //found 为 bool 值, true = found
- if found {
- fmt.Println("found, and the value = ", b)
- } else {
- fmt.Println("not found")
- }
- map1["b"] = "456"
- fmt.Println("map1 = ", map1) //map1 = map[a:123 b:456]
- delete(map1, "b") //删除键为"a"的键值对
- fmt.Println("map1 = ", map1) //map1 = map[b:456]
- fmt.Println("len(map1) = ", len(map1)) //len(map1) = 1
- //fmt.Println("cap(map1) = ", cap(map1)) // invalid argument map1 (type map[string]string) for cap
- map2 := map1
- map2["a"] = "789"
- fmt.Println("map1 = ", map1) //map1 = map[a:789],其值为发生改变,因为map2和map1是同一地址空间
- }
- func changeValue(arr [3]int) {
- arr[0] = 100
- fmt.Println("changeValue: ", arr) //changeValue: [100 5 6]
- }
- func changeValue2(slc []int) {
- slc[0] = 5
- fmt.Println("changeValue2: ", slc) //changeValue2: [5 2 3]
- }
运行结果:
go - 复合类型 array, slice, map的更多相关文章
- Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)
本博文的主要内容如下: Hive文件存储格式 Hive 操作之表操作:创建外.内部表 Hive操作之表操作:表查询 Hive操作之表操作:数据加载 Hive操作之表操作:插入单表.插入多表 Hive语 ...
- go语言 类型:基础类型和复合类型
Go 语言中包括以下内置基础类型:布尔型:bool整型:int int64 int32 int16 int8 uint8(byte) uint16 uint32 uint64 uint浮点型:floa ...
- hive原生和复合类型的数据载入和使用
原生类型 原生类型包含TINYINT,SMALLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE,STRING,BINARY (Hive 0.8.0以上才可用),TIMESTAM ...
- JS中集合对象(Array、Map、Set)及类数组对象的使用与对比
原文地址 在使用js编程的时候,常常会用到集合对象,集合对象其实是一种泛型,在js中没有明确的规定其内元素的类型,但在强类型语言譬如Java中泛型强制要求指定类型. ES6引入了iterable类型, ...
- Golang - 复合类型
目录 Golang - 复合类型 1. 指针 2. new()和make() 3. 数组 4. slice 5. Map 6. 结构体 7. 结构体参数 Golang - 复合类型 1. 指针 go语 ...
- JS中集合对象(Array、Map、Set)及类数组对象的使用与对比(转载)
在使用js编程的时候,常常会用到集合对象,集合对象其实是一种泛型,在js中没有明确的规定其内元素的类型,但在强类型语言譬如Java中泛型强制要求指定类型. ES6引入了iterable类型,Array ...
- 带你学够浪:Go语言基础系列 - 8分钟学复合类型
★ 文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) " 对于一般的语言使用者来说 ,20% ...
- 003-Tuple、Array、Map与文件操作入门实战
003-Tuple.Array.Map与文件操作入门实战 Tuple 各个元素可以类型不同 注意索引的方式 下标从1开始 灵活 Array 注意for循环的until用法 数组的索引方式 上面的for ...
- 第54讲:Scala中复合类型实战详解
今天学习了scala的复合类型的内容,让我们通过实战来看看代码: trait Compound_Type1trait Compound_Type2class Compound_Type extends ...
随机推荐
- hdu 4756 Install Air Conditioning
非正规做法,一个一个的暴,减一下枝,还得采用sort,qsort居然过不了…… #include <cstdio> #include <cmath> #include < ...
- Swift自适应布局(Adaptive Layout)教程(二)
给TextContainer中添加内容 打开 Main.storyboard ,从组件库(Object Library)中拖拽两个 Label 组件到TextContainer中,位置可以随意摆放: ...
- sqlite创建数据库问题
1.<Sqlite权威指南>上说是这么创建数据库的: sqlite3 test.db 但是我写了这条语句之后出现了下面的情况(注:安装Sqlite过程见 ...) 我的sqlite3放在 ...
- 使用Dataset
string sqlStr="Select * from Tb_news"; SqlDataAdapter myDa=new SqlDataAdapter(SqlStr,myCon ...
- android Log.isLoggable步骤的使用
原文地址: http://www.cnblogs.com/maxinliang/p/4024442.html android Log.isLoggable方法的使用 android 动态控制logca ...
- html5新特性--音频视频,拖放
1.音频 <audio controls> <source src="aaa.ogg" type="audio/ogg"> <so ...
- ashx ajax 与 自定义javascript函数
1.getUserPower为自定义javascript函数 获取权限 (1).ashx 处理程序的相对地址(必须是相对地址) (2).au 权限名称 (3).classname 类名 (4) ...
- coconHashMap实现原理分析
1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1 ...
- ssh-agent自启动加key脚本
公司使用到阿里云. 需要使用 ssh-agent forward 来跳转.为了方便自己就写了这个脚本 1 #!/bin/sh 2 # auto start ssh-agent and add key ...
- 帝国cms实现自动生成缩略图和自动分页功能
无论你手工发布,还是采集而来,免不了要进行手工操作弄缩略图,不然标题图片没有,挺烦人的 只需一次设定,就可以在文章编辑框里自动勾选上分页和生成缩略图,免除你次次进行操作的麻烦,好了,废话不多说,上菜“ ...