go语言学习 二

Go语言里和c语言一样也有指针的概念  

var i int = 1

var pInt *int = &i

//输出:i=1     pInt=0xf8400371b0       *pInt=1

fmt.Printf("i=%d\tpInt=%p\t*pInt=%d\n", i, pInt, *pInt)

*pInt = 2

//输出:i=2     pInt=0xf8400371b0       *pInt=2

fmt.Printf("i=%d\tpInt=%p\t*pInt=%d\n", i, pInt, *pInt)

i = 3

//输出:i=3     pInt=0xf8400371b0       *pInt=3

fmt.Printf("i=%d\tpInt=%p\t*pInt=%d\n", i, pInt, *pInt)

 

对于指针要了解的更多是指针的定义方式,使用和c语言也是一样的,指针的使用应该还是会出现很多坑,所以以后如果发现了再细做详解,对于定义方式go语言可以说都是和c语言反过来的,

 

对于内存分配c语言和c++有不同的方式 c主要是malloc realloc calloc 而c++里边则是new new和malloc最大的区别在我看来就是new在定义自定义类型的时候 会调用这些类的构造函数,在delete会直接调用析构函数 在go语言里边有两种分配机分别是内建的函数new和make,他们所做的事情不同,所应用到的类型也不同

 

new是一个分配内存的内建函数, 但不同于其他语言中同名的new所做的工作,他只是将内存清零,而不是初始化内存,new(T)为一个类型为T的新项目分配了值为0的存储空间, 并且返回其地址,也就是一个类型为*T的值,用go的术语来说,就是他返回了一个指向新分配的类型为T的0值的指针,make(T,args)函数的目的与new(T)不同,他仅用于创建切片、map和chan(消息管道),并返回类型T(这里要注意不是返回T*)的一个被初始化了的不是0的实例,这种差别的出现是由于这三种类型实质上是对在使用前必须进行初始户的数据的引用,例如切片是一个具有三项内容的描述符 包括只想数据 的指针,长度以及容量, 在这三项内容被初始化之前,切片值为nil,对于切片映射和信道,make初始化了其内部的数据结构并准备了将要使用的值。

var p *[]int = new([]int)   // 为切片结构分配内存;*p == nil;很少使用

var v  []int = make([]int, 10) // 切片v现在是对一个新的有10个整数的数组的引用

// 不必要地使问题复杂化:

var p *[]int = new([]int)

fmt.Println(p) //输出:&[]

*p = make([]int, 10, 10)

fmt.Println(p) //输出:&[0 0 0 0 0 0 0 0 0 0]

fmt.Println((*p)[2]) //输出: 0

// 习惯用法:

v := make([]int, 10)

fmt.Println(v) //输出:[0 0 0 0 0 0 0 0 0 0]

这段代码 是new和make的区别,不过理解的还是不太透彻,看样子new在go语言里边使用的很少,new申请出来的空间还是需要经过make来进行初始化这里说的是 make是用来初始化三种数据slice map channel,对于map好理解接触过一点点,对于channel是一点都不理解,暂时不考虑,slice到底是个什么

在go语言里边数组是具有固定长度的并且拥有0个或者多个相同或者相同数据类型元素的序列,由于数组长度固定,所以在go语言比较少直接使用,而slice长度可增可减,使用场合就比较多,其实在我看来就是c语言里边普通数组和c++里边vector的区别。slice让程序员更加省心。vector本质在学习的时候了解过就是三个指针来实现的,而slice也是有三个属性,分别是指针、长度和容量 指针可以理解成我们访问数组指定内容的下标,长度是slice中含有的元素个数,容量就是他可以放下多少数据,在go语言里边可以用内置函数 len和cap来返回slice的长度和容量。在slice里追加元素的时候如果容量不足,一般来说会扩容到原来的两倍。对于更加详细的理解会在以后遇到后进行更加深入的了解。

 

在go语言中还有一个东西叫做切片切片通俗 的来说就是对数组的某一段数据的引用

 

package main

 

import "fmt"

 

func main() {

    names := [4]string{

        "John",

        "Paul",

        "George",

        "Ringo",

    }

    fmt.Println(names)

 

    a := names[0:2]

    b := names[1:3]

    fmt.Println(a, b)

 

    b[0] = "XXX"

    fmt.Println(a, b)

    fmt.Println(names)

}

来看这个程序 这个程序的输出

可以看出来 a是names的一段引用,b也是names的一段引用,并且他们都有重合的部分,当我们对这些引用进行修改的时候那整个数组都会被更改。

切片他会更像一种没有长度的数组,他在定义数组的时候不要指定确切的长度。

在切片的时候也可以默认他的上下界 

如果第一个数字不指定就是从第一个数据开始,最后一个不指定就是到最后一个数据结束,自然如果两个都不指定那就是全部数据。

S先是被填充了6个数字,然后截取了1-4 切片默认是左闭右开的 所以是从下标为1的开始到3的放进去,4没有进去。然后再次切片的时候从0开始到2不包括2结束,第三次从1开始到最后他就是最后所以直接结束。

 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页