撸起袖子加油干 golang入坑系列

还是提醒一下,里面有段子,不都是技术。 冲着技术来的,慢走不送。没有版权,但可以给我发邮件(ztao8607@gmail.com)

在我的发小朋友中,终于最后一位打光棍的要结婚了。 说实话,真心不容易。相亲七八次,女方年龄上至32,下至23。跨度之大,范围之广,在我的发小界相当罕见。 扪心自问,程序员都怎么了?为什么找个女朋友结婚会如此艰难。 是coder们不解风情?还是被岛国妹子蒙蔽了心灵?若说木讷,内向。那恐怕是对码农们最大的误解了,在他们一副不愿说话的面具之下都暗藏着一颗汹涌澎湃的内心,时时刻刻在迸发着灵感。但至于这份灵感几分用于妹子身上,那就尚未可知了。也见过舌尖口利,口若悬河的屌丝,但这种状态经常出现在与人争论技术问题之时,如若对面站的是一个萌妹子,恐怕再多的hello world也要return回肚子里面。所以,我这位发小找不到另一半,的确是有原因的。 还好,经过全方位不歇的努力,终于找到了一个懂得撬开这位愣头青口舌的妹子。所以,借此祝愿二位喜结良缘,白头到老,撸起袖子加油干!

书接上文,继续来聊Golang中常见的数据类型。

在上篇中,说到了String。本节来看数组Array。若你还有印象,想必在大学课堂之上肯定会有一门<数据结构>的课程。这门课程应该是计算机专业的奠基之课,学好了这门课,即便你不会写代码也不耽误你找份好工作。如果又学好了算法,即便你不会写代码,也不耽误你去BAT实习。

而数组就是一种常见的数据结构。 这里没法从数据结构的角度来讲数组,因为我自认对此并不精通,讲不好不如不讲。 有兴趣,建议翻看大学数据结构的教材,看懂那本就够了。

Golang的数组从数据结构的角度来说,和其它语言没什么区别。都是链式存储数据,存储相同类型的数据。数组下标同样从0开始计数,通过[]来顺序访问。例如:

intList[0] intList[1] ... intList[99]

声明数组最常用的方法是下面这种:

var arrayname[SIZE] type

这是最常用的单维数组(只有一个维度的数组),相对应的会存在多维数组,例如二维数组。二维数组的每一项都是另外一个数组,因此可以理解成存放数组的数组。

当使用上面语句声明变量时,Size必须是一个大于零的整数常量,而类型可以是任何合法的数据类型(包括内置的基本类型或者自定义的数据类型)。

例如,我们声明一个长度为10的整型数组:

var intList[10] int

在<准备冲锋>一节中,可以看到变量声明之外,如果是基本数据类型的变量,golang会自动完成初始化。 那数组呢?golang会不会自动完成初始化。你可以自己动手写段代码试一下。如果不想写,直接拿走下面的代码:

package main

import (
    "fmt"
)

func main() {
    var intList [10]int
    fmt.Println(intList[1])
    fmt.Println(intList[9])
}

任意访问两个元素,结果都是0. 换成其它类型,看看结果。实际结果表明,如果是基本数据类型,golang同样会对数组元素进行初始化。在上例当中,所有元素都初始化成了0. 如果想初始化其它数据怎么办?Easy,使用下面的语法:

var name = [SIZE]type{ value, value .... }

从语法上面来看,就是一个二合一。 首先声明数组,然后对数组中每个元素进行赋值,借此完成数据初始化的目的。比如下面:

var intList = [5]int{1,2,3,4,5}

在运行一下代码,看看结果:

package main

import (
    "fmt"
)

func main() {
    var intList = [5]int{1,2,3,4,5}
    fmt.Println(intList[1])
    fmt.Println(intList[4])
}

这种方式是常用的初始化方式,再说一点不太常用,但面试的时候容易被人提及的(正常情况下,使用概率低于10%).

隐式长度

var intList = []int{1,3,4,5,6}

事先不声明长度,依靠后面初始值的长度来确定数组长度,没啥可说的,技巧而已。

比这个刚常用的是:

var intList []int
intList = append(intList,10)

但此时intList已经变成切片类型了。 切片和数组还是有所不同的,在下节会讲到切片类型,这里只剧透一下。

数组初始化完成之后,在后面的程序中都可以直接使用了。 而使用的方式,就是通过下标依次取出进行赋值或者取值操作。例如:

// 直接拷贝个源代码,用来说明问题
package main

import "fmt"

func main() {
   var n [10]int
   var i,j int

   for i = 0; i < 10; i++ {
      n[i] = i + 100 
   }

   for j = 0; j < 10; j++ {
      fmt.Printf("Element[%d] = %d\n", j, n[j] )
   }
}

Golang最基本的数组用法就是这些,在开始的时候说过,最常用的是一维数组,多维数组使用不算太多(尤其超过二维的数组,用之甚少),因此使用一点篇幅来说一下多维数组的使用。

首先是多维数组的声明,看着负责,其实不难:

var name [SIZE1][SIZE2][SIZE3]....type

既然是数组,就要遵循数组的规范,无论是多维数组还是单维数组,其中的元素必须是同一种数据类型,所以可以看到最后只有一种type。

而上面多个SIZE的个数表示的是维度,上面有三个SIZE表示的是三维(例如经常说的长高宽,如果你非要理解成那个三维,随便你,也没错)。如果只有[SIZE1][SIZE2]就表示是二维。

多维数组的初始化和一维一样(其实我们可以将多维数组降维成一维),看下面:

var a = [3][4]int{  
   {0, 1, 2, 3} ,   
   {4, 5, 6, 7} ,   
   {8, 9, 10, 11}   
}

a是一个二维数组,在第一维上面有三个元素,每个元素是一个数组(这个数组是一个保存四个元素的单维数组)。所以这个数组的初始化,就是同时完成多个数组的初始化。

多维数组的访问,仍然遵循下标访问的规则。 例如需要取出上面数组中的8,那就是 a[2][0]。 因为8所在的数组是a数组的第三个元素,所以先取出a[2],而这个a[2]是一个数组,8是这个数组的第一个元素,所以a[2][0]就是8。

熟能生巧,唯手熟尔。 所以遇到不明白的地方,多写几段代码看看效果。

最后问个小问题,让你来回答。

提问:[5]int 和 []int 是不是同一种数据类型

回答: XXXX

还是那句话,写段代码验证一下。

package main

import "fmt"

func main() {
    var s []int
    s = append(s, 10)
    printArray(s)
}

func printArray(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

如果把printArray的参数由[]int 替换成 [5]int,看看什么效果。 恩,报错。 会提示你类型不一致。这点是刚开始写golang代码时容易混淆的地方,[5]int是数组类型,而[]int则是切片类型。因此会报错。

在实际编程经验中,数组使用率反而不如切片高。这又是为何呢? 还不点个star,订阅下一节。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C语言及其他语言

[每日一题]宏定义

前面题目主要是自定义函数的题,相信经过这些题目的训练,大家对自定义函数的理解想必更近了一步。接下来呢,我们主要来练习跟自定义函数异曲同工的宏定义,先看看下面这题...

3476
来自专栏数据结构与算法

P2375 动物园

题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了。例如企鹅,只会卖萌向游客要吃的。为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决...

2856
来自专栏ml

排序一栏(总结帖)

      学了很多的排序,基数排序,堆排序,希尔排序,选择排序,归并排序,快速排序,冒泡排序.....等等,尽管网上好文,如堆山之牛毛,但是还是没有自己写,来...

2123
来自专栏ACM算法日常

POJ-3275:奶牛排序Ranking the Cows(Floyd、bitset)

Each of Farmer John's N cows (1 ≤ N ≤ 1,000) produces milk at a different positi...

1162
来自专栏编程直播室

读书笔记:《算法图解》第三章 递归

1625
来自专栏雪胖纸的玩蛇日常

4. 高等数学——元素和极限

  假设我们知道了整数的定义,像-3,1,17这些都属于整数Z。然后有理数则是两个整数相除q/p ,q,p属于Z,则是有理数Q。

942
来自专栏数据结构与算法

1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛

1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond...

45110
来自专栏移动端开发

Swift 基础部分(建议掌握OC字符串知识的翻阅)

更新说明:         Swift 目前已经发布到4.0版本了,以前写的这整个Swift学习系列的文章,有很多的不足之处,我会重新整理整个系列文章,也是相...

1919
来自专栏cs

递归算法

据说凡是可以循环的步骤,都可以递归表示出来。 递归的关键有二点: 1.0 递归公式,即递推式。 2.0 递归出口。 ---- 递归求数组的和 package...

3865
来自专栏Python

初识面向对象

面向过程 VS 面向对象  面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理...

20510

扫码关注云+社区

领取腾讯云代金券