Golang 中的指针 - Pointer

Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, func 。
 
相比 Java,Python,Javascript 等引用类型的语言,Golang 拥有类似C语言的指针这个相对古老的特性。但不同于 C 语言,Golang 的指针是单独的类型,而不是 C 语言中的 int 类型,而且也不能对指针做整数运算。从这一点看,Golang 的指针基本就是一种引用。
 
那么 Golang 为什么需要指针?这种指针又能有什么独特的用途呢?
 
在学习引用类型语言的时候,总是要先搞清楚,当给一个函数/方法传参的时候,传进去的是值还是引用。实际上,在大部分引用型语言里,参数为基本类型时,传进去的大都是值,也就是另外复制了一份参数到当前的函数调用栈。参数为高级类型时,传进去的基本都是引用。这个主要是因为虚拟机的内存管理导致的。
 
内存管理中的内存区域一般包括 heap 和 stack, stack 主要用来存储当前调用栈用到的简单类型数据:string,boolean,int,float 等。这些类型的内存占用小,容易回收,基本上它们的值和指针占用的空间差不多,因此可以直接复制,GC也比较容易做针对性的优化。 复杂的高级类型占用的内存往往相对较大,存储在 heap 中,GC 回收频率相对较低,代价也较大,因此传引用/指针可以避免进行成本较高的复制操作,并且节省内存,提高程序运行效率。
 
因此,在下列情况可以考虑使用指针:1,需要改变参数的值;2,避免复制操作;3,节省内存;
 
而在 Golang 中,具体到高级类型 struct,slice,map,也各有不同。实际上,只有 struct 的使用有点复杂,slice,map,chan 都可以直接使用,不用考虑是值还是指针。
 
 
struct:
 
对于函数(function),由函数的参数类型指定,传入的参数的类型不对会报错。
对于方法(method),接收者(receiver)可以是指针,也可以是值,Golang 会在传递参数前自动适配以符合参数的类型。也就是:如果方法的参数是值,那么按照传值的方式 ,方法内部对struct的改动无法作用在外部的变量上。
方法是包含了接收者的函数。
函数的格式是固定的,func 函数名 参数 返回值(可选) 函数体。
 
slice :
 
slice 实际上相当于对其依附的 array 的引用,它不存储数据,只是对 array 进行描述。因此,修改 slice 中的元素,改变会体现在 array 上,当然也会体现在该 array 的所有 slice 上。
可以使用 make([]int) 来创建并初始化 map 。
  
map :
 
使用 make(map[string]string) 返回的本身是个引用,可以直接用来操作。
chan :
 
make(chan int) 返回的是可以直接使用的 channel 。
  
func :
 
在 Golang 中,func 可以作为一种值被返回,因此也可以使用类似 Python 的 decorator 的方式来加工函数。
 
接口指针:
  1. 指针的判断,都涉及到type和value。
  2. 接口指针之间的判等,要基于type与value,一个不同则不等。
  3. 接口指针与其对应实现的结构体指针,可以进行判等操作。

------------------------------------------------------------- ------------------------------------------------------------

数组切片内容复制 copy

用于将内容从一个数组切片复制到另一个数组切片。如果加入的两个数组切片不一样大,就会按其中较小的那个数组切片的元素个数进行复制。

slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3} copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置

go 源码中 slice 的数据结构定义

type slice struct {
array unsafe.Pointer
len int
cap int
}

实际go在append的时候放大cap是有规律的。在 cap 小于1024的情况下是每次扩大到 2 * cap ,当大于1024之后就每次扩大到 1.25 * cap 。

这个是 slice 的数据结构,它很简单,一个指向真实 array 地址的指针 ptr ,slice 的长度 len 和容量 cap 。


其中 len 和 cap 就是我们在调用 len(slice) 和 cap(slice) 返回的值。

slice:用来弥补数组的不足,称之为数组切片

创建数组切片的方式

1:基于数组

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

var slice []int = array[:5] //基于数组的前5个元素创建数组切片

2:直接创建

slice := make([]int,5,10) //创建一个初始元素个数为5,初始值为0,并预留10个元素的存储                                            空间的数组切片

内置函数:

cap():返回数组切片分配的空间大小

len():返回数组切片当前所存储的元素个数

  

golang 小知识-持续更新中的更多相关文章

  1. Mysql注入小tips --持续更新中

    学习Web安全好几年了,接触最多的是Sql注入,一直最不熟悉的也是Sql注入.OWASP中,Sql注入危害绝对是Top1.花了一点时间研究了下Mysql类型的注入. 文章中的tips将会持续更新,先说 ...

  2. linux常用小技巧(持续更新中)

    一.设置固定ip地址1.config查看用的是哪一个网卡这是假设用的是eth12.修改dns地址vim /etc/resolv.confsearch 域名地址nameserver 192.168.3. ...

  3. 【前端面试】Vue面试题总结(持续更新中)

    Vue面试题总结(持续更新中) 题目参考链接 https://blog.csdn.net/weixin_45257157/article/details/106215158 由于已经有很多前辈深造VU ...

  4. Pig基础学习【持续更新中】

    *本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.* Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的,可以作为MapR ...

  5. Pig语言基础-【持续更新中】

      ***本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.***   Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的, ...

  6. java视频教程 Java自学视频整理(持续更新中...)

    视频教程,马士兵java视频教程,java视频 1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播 ...

  7. 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

    Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...

  8. fastadmin 后台管理框架使用技巧(持续更新中)

    fastadmin 后台管理框架使用技巧(持续更新中) FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架,具体介绍,请查看文档,文档地址为:https://doc. ...

  9. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

随机推荐

  1. 【Visual Studio】VS常用调试技巧——笔记

    CSDN的文档: https://msdn.microsoft.com/en-us/library/aa295838(v=vs.60).aspx 情景一:[监视]变量时,当运行离开当前函数后,怎么看到 ...

  2. SQL Server 2008 压缩日志

    USE [master]GOALTER DATABASE DNName SET RECOVERY SIMPLE WITH NO_WAITGOALTER DATABASE DNName SET RECO ...

  3. 函数调用前有"::"符号,什么意思啊?

    struct ifreq ifrf; ::memset(&ifrf,0,sizeof(ifrf)); ::strncpy(ifrf.ifr_name, ifr[addrCount].ifr_n ...

  4. Android-——多线程之Handler(转)

    Android--多线程之Handler 原文地址:http://www.cnblogs.com/shirley-1019/p/3557800.html 前言 Android的消息传递机制是另外一种形 ...

  5. Linux启动与禁止SSH用户及IP的登录

    以下就针对SSH方面讨论一下.假设有人特别关注Linux环境的安全性,第一就从login方面来进行讨论 1:Linux启动或禁止SSH root用户的登录 2:Linux限制SSH用户 事实上这些东西 ...

  6. LINQ操作符一:Select

    一.什么是LINQ?它可以用来做什么 语言集成查询(Language Integrated Query,LINQ)是一系列标准查询操作符的集合,这些操作符几乎对每一种数据源的导航.过滤和执行操作都提供 ...

  7. .net垃圾回收

    垃圾回收器(gc)用来在.NET中进行内存管理,特别是它可以恢复正在运行的应用程序需要的内存. .NET运行库采用的方法是垃圾回收器,这是一个程序,其目的是清理内存.方法是所有动态请求的内存都分配到堆 ...

  8. MySql: ”Commands out of sync“Error (Connect/C++)

    使用 Connector/C++ 查询 Mysql , 连续调用存储过程时 会出现如下: Commands out of sync; you can't run this command now,st ...

  9. jquery javascript 回到顶部功能

    今天搞了一个回到顶部的JS JQ功能 (function($){ $.fn.survey=function(options){ var defaults={width:"298", ...

  10. Hadoop书签

    1)http://www.cnblogs.com/forfuture1978/archive/2010/03/14/1685351.html 2)http://www.cnblogs.com/sund ...