>

在使用切片的时候,golang中的数组与C语言中的数

- 编辑:澳门博发娱乐官网 -

在使用切片的时候,golang中的数组与C语言中的数

这里不介绍数组和切片的使用技巧,主要看下2者的区别。

C#安装

学习C#视频链接:

可以到官网查看安装包或百度下载
下载地址:(官网下载的很容易安装失败啊,还是按照下方的地址安装吧)

VisualStudio2015安装参考教程:

  1. 下载和安装教程
  2. 使用百度网盘下载ed2k方法

前言

golang复合类型包括:结构体、数组、切片、Maps。

前言

上篇内容,介绍了如何在不同的系统上安装 Go 开发环境和部分参数的配置,也简单介绍了 package 的概念、导入方式和我对包的初始化过程的理解,关于初始化顺序的理解,可能有错误,后期会有修改,也希望大家能指出来,帮助我学习下,谢谢。

这篇内容,讲些基础的知识,比如变量的声明方式、变量的重声明和重命名区别。

首先看下它们的定义:

基础知识

Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素:

1、数组

变量的声明

Go 语言中,变量的声明有几种方式,如:

var i,j int = 1,2var i,j = 1,"2"i,j,k := 1,"2",truevar (    m int=4    n = "Golang"    r = true)

这里面比较特殊的是 i,j,k := 1,"2",true ,这在 Go 语言里被称为短声明,它有一个特殊点,就是不能在包级作用域中使用,只能在函数或块中使用。这里涉及到我要讲的两个知识点,变量重声明重名变量

  • 数组:类型[n]T表示拥有nT类型的值的数组。
  • 切片:类型[]T表示一个元素类型为T的切片。

编码规范

图片 1

  • 指向底层数组的指针
  • slice目前使用到的底层数组的元素个数,即长度
  • 底层数组的最大长度,即容量

数组

变量的重声明

什么是变量的重声明?让我们用个例子来解释吧:

var err errorn,err:=io.WriteString(os.Stdout,"Hello world!n")

从代码中我们看到,err 在第一行被声明了,接着我们又使用短声明的方式重新给它了值,注意这里没有变量重名即变量覆盖,发生的是变量重声明,这些代码在一个代码块中,如果你不确定,可以输出下变量地址看看是否有改变。这里我们先注意下变量重声明的前提条件,如下:

  1. 由于变量的类型在初始化时就已经确定,所以再次声明时赋予的类型必须与原本的相同,否则编译报错。

  2. 变量的声明只能发生在同一个代码块中。如果是与不同的代码块的变量重名,那么就是变量重名了,下文会介绍。

  3. 变量的重声明只有在短变量声明时才会发生,否则便已报错。

  4. 被声明的变量必须有多个,而且其中至少有一个新变量,而且不能使用 *_* 表示新变量。

上面提到了变量重名,如果你是个老鸟,那么你肯定知道,你可以略过这个例子了:

var name = "Tom"{    name := []string{"Jerry"}    fmt.Printf("%vn",name)}fmt.Printf("%sn",name)

也许心细如你,发现了不同,没错这两次变量的声明发生在了不同的代码块,这次就是变量的覆盖了,好了现在我们可以总结下两者的区别了

  1. 变量的重声明必须在同一代码块中,注意是 同一代码
  2. 变量重声明是对同一变量的的多次声明,即变量只有一个。
  3. 变量重声明,不论多少次其类型始终一致,必须遵从它的次声明指定的类型。而重名变量则不存在类型一致的限制,可以是任意不同类型。
  4. 如果可重名变量所在代码存在直接或间接的嵌套关系v,那么肯定会存在“屏蔽”现象,而变量重声明不会。

看一个数组的例子:

初识C#代码

using System;
using System.Collections.Generic;
using System.Text;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            const string CITY = "布宜诺斯艾利斯";//常量,城市
            const string NAME = "列奥波尔多·福图纳托·加尔铁里·卡斯特利";//常量,姓名
            Console.WriteLine(NAME+"出生在"+CITY+"的一个工人家庭");//使用常量
            Console.Write('hello word');//输出不换行
        }
    }
}
  1. ///是文档注释,只能写在类、方法、属性的前面。不能用来注释单个变量。
  2. c#中的关键字都是小写,比如static,namespace ,void ,const ……..
  3. double关键字表示一种数据类型——双精度浮点型。const才是声明常量的关键字。
  4. C#中没有boolean类型

因此当我们定义一个切片变量,s := make([]int, 5, 10),即为指向了一个最大长度为10的底层数组,目前切片s使用到的长度为5。

golang中的数组与C语言中的数组差异很大,倒更类似Pascal中的数组。 (Slice,下个话题,有些像C语言中的数组)

数组和切片

数组类型和切片类型,两者都属于集合类型,都是存储了某一类型的值,这么看貌似它们没有什么区别,先让我们通过几个简单的例子看下区别。

数组的长度在声明时就需要给定,以后对其的使用是不能改变其长度的,也就是说长度是类型的一部分。

比如[5]int与[6]int是不同的两种数组类型;然后切片的类型字面量中只有元素的类型,而没有其长度。换句话说,切片的长度可以随着其中的元素增长而增长,但不会随着减少而减少。让我们看下几个示例,如下:

// 一维数组array1 :=[6]int// 二维数组array2 :=[10][20]string// 这里还是数组,自动计算数组的长度array3 :=[...]int{10,20,30,40}// 切片,len=1slice1 :=[]int{1}// 声明一个长度为5,但容量为10的string类型的切片,长度和容量都是可变。容量参数10可省略,那么该slice的容量跟长度一致都是5slice3 := make([]string,5,10)// 连续插入多个值,其实后面也是个sliceslice1=append(slice1,2,3,4)// 从slice1第二个素开始取出两个并组成一个新的切片,slice1和slice2是共享一个底层数组的。len=2,cap=3slice2:=slice1[1:3]// 如果这里修改了slice2的第一个元素值,slice1会有变化么,想想,不确定的话可以自己尝试输出下slice2[0]=-2// 这里又声明了slice4,似乎与slice2有些区别,那么区别在哪呢?slice4:=slice1[1:3:3]

看了上面的示例代码,也许对切片会有更多的疑惑,别急现在我们一一解答。

示例代码中 slice2:=slice1[1:3] 这里使用切片slice1创建了一个新切片,其长度 lencap 分别是2,3。为什么其容量是3呢?先解释下这个声明语句,slice1[1:3] 第一个值表示新切片开始的元素位置,这里是1,表示是从slice1的第二元素开始。第二个值表示开始的索引位置,加上希望包含的元素个数,1+2的结果就是3,所以第二个值就是3,但要注意这里是不包含第二个值代表的索引位置的值,这里是数学中前开后闭的区间。那么第二个切片的容量怎么计算的呢?由于两个切片共享同一个底层数组,底层数组的容量是4,由于slice2是从索引位置为开始,那么slice2的容量就是4-1=3,所以容量就是3。由于这两个切片共享同一个底层数组,所以 slice2[0]=-2 语句是修改的底层数组的值,对应的slice1[1]位置的值也被修改。想一下下面的代码输出结果是什么?

slice1:=[]int{1,2,3,4}slice2:=slice1[1:3]slice2=appendfmt.Printf("s1:%vn",slice1)fmt.Printf("s2:%vn",slice2)

你想到的输出结果,跟下面一样么?

s1:[]{1,2,3,5}s2:[]{2,3,5}

上面提到 slice2:=slice1[1:3] 中有第三个参数,新切片的容量,默认是可忽略的,此时新切片的容量是 cap-1 。你也可以加入第三个参数,但你要记住它是不能超过底层数组的容量的,也不能小于第二个参数值否则编译报错,如 slice2:=slice1[1:3:3] ,此时新切片的容量变成了3-1=2,跟长度一致,但前提是cap的容量不能超过底层数组的容量cap,也不能少于len。想一下,第三个参数有什么作用呢?

本文由胜博发-编程发布,转载请注明来源:在使用切片的时候,golang中的数组与C语言中的数