指针

  本章围绕字符串、数字、数组、切片、map、channel、结构体与指针赋值及函数传参的应用剖析

字符串

字符串本身也是StringHeader的结构体,包含Data指针与字符串长度,如下

type StringHeader struct {
Data uintptr
Len int
}

Data指向的内存地址不可更改,字符串赋值和传参只是拷贝了StringHeader中Data和Len的值

package main

import "fmt"

func main()  {
str := "Hello World!"
var data string
data = str
// 拷贝str中Data与Len
fmt.Println(data)
data = "Hello Go!"
// 修改data的值 在内存中生成新的StringHeader结构体 并赋值给data
fmt.Println(data)
// str内存未改变
fmt.Println(str)
} //Hello World!
//Hello Go!
//Hello World!

当声明变量为字符串指针时,变量赋值时对象一定是字符串内存地址,函数传参时拷贝的也是内存地址而已 

package main

import "fmt"

func main()  {
str := "Hello World!"
var ptr *string
// 错误方法 str是字符串类型非指针类型
//ptr = str
// 正确方式 获取str的地址 赋值给ptr
ptr = &str fmt.Println(ptr)
fmt.Println(*ptr)
} //0xc0000421c0
//Hello World!

  

 数字

数字未找到对应的结构体,数字类型赋值、指针、函数传参与字符串一致,不可修改(修改等同于重新赋值)

package main

import "fmt"

func main()  {

	number := 10
var ptr *int
// 错误方法 str是字符串类型非指针类型
//ptr = str
// 正确方式 获取str的地址 赋值给ptr
ptr = &number fmt.Println(ptr)
fmt.Println(*ptr)
} //0xc00000a0b8
//10

  

 数组

数组赋值、函数传参时,进行都是内存拷贝,数据都会拷贝一份,新的数组修改不影响被赋值的数组

package main

import "fmt"

func main()  {
list1 := [4] int{1,2,3,4} list2 := list1
list2[0] =100
fmt.Println(list1)
fmt.Println(list2)
} //[1 2 3 4]
//[100 2 3 4]

数组指针,指针修改时不需要加*的;修改时,原数组更改

package main

import "fmt"

func main()  {
list := [4]int{1,2,3,4}
// 声明时指定数组大小
var ptr *[4]int
ptr = &list
// 错误赋值
//*ptr[0] =100
// 正确方式
ptr[0] = 100
fmt.Println(list)
fmt.Println(*ptr)
} //[100 2 3 4]
//[100 2 3 4]

切片

切片结构体 SliceHeader 如下

type SliceHeader struct {
// 指向数组内存地址 赋值时拷贝的是数组地址
Data uintptr
// 长度
Len int
// 申请空间
Cap int
}

赋值、copy、函数传参时只是拷贝了结构体中的变量。详情Go语言【数据结构】切片

package main

import "fmt"

func main()  {
slice1 := []int{1,2,3,4} slice2 := slice1
slice2[0] =100
fmt.Println(slice1)
fmt.Println(slice2)
} //[100 2 3 4]
//[100 2 3 4]

切片指针,下面方式都不可以修改

package main

import "fmt"

func main() {
slice1 := []int{1,2,3,4}
var ptr *[]int
ptr = &slice1 // 下面两种方式都不可以修改
ptr[0] =100
*ptr[0] =100
fmt.Println(slice1)
fmt.Println(*ptr)
} //[1 2 3 4]
//[1 2 3 4]

  

channel

通道在赋值时,指向的都是同一块内存地址

package main

import "fmt"

func main() {
chan1 := make(chan string,1)
chan2 := chan1
chan2 <- "hello"
data := <-chan1
fmt.Println(data)
// 指向同一块地址
fmt.Println(chan1)
fmt.Println(chan2)
} //hello
//0xc000088000
//0xc000088000

同时,通道也支持指针

package main

import "fmt"

func main() {
chan1 := make(chan string,1)
chan2 := &chan1
*chan2 <- "hello"
data := <-chan1
fmt.Println(data)
fmt.Println(chan1)
fmt.Println(chan2)
} //hello
//0xc000038060
//0xc000006028

  

结构体 

那么重点来了,结构体赋值和指针有何区别,先看戏结构体生成的三种方式,其中第二种方式和第三中方式一致

package main

import "fmt"

type Phone struct {
color string
name string
} func main() {
// 第一种生成方式 生成结构体对象
phone1 :=Phone{"Red","Iphone"}
fmt.Println(phone1.color)
fmt.Println(phone1.name)
fmt.Println(phone1) // 第二种生成方式 生成结构体指针
phone2 :=&Phone{"Red","Iphone"}
fmt.Println(phone2.color)
fmt.Println(phone2.name)
fmt.Println(phone2) // 第三种生成方式 生成结构体指针
phone3 := new(Phone)
phone3.color = "Red"
phone3.name = "Iphone"
fmt.Println(phone3.color)
fmt.Println(phone3.name)
fmt.Println(phone3)
} //Red
//Iphone
//{Red Iphone}
//Red
//Iphone
//&{Red Iphone}
//Red
//Iphone
//&{Red Iphone}

结构体赋值,等同于拷贝了结构体中的变量,函数传参与赋值一样

package main

import "fmt"

type Phone struct {
color string
name string
} func main() {
// 赋值
phone1 :=Phone{"Red","Iphone"} phone2 := phone1
phone2.color = "Green"
fmt.Println(phone1.color)
fmt.Println(phone2.color)
} //Red
//Green

而指针只是拷贝了结构体的内存地址,修改会影响原来的值

package main

import "fmt"

type Phone struct {
color string
name string
} func main() {
// 赋值
phone1 :=&Phone{"Red","Iphone"} phone2 := phone1
phone2.color = "Green"
fmt.Println(phone1.color)
fmt.Println(phone2.color)
} //Green
//Green

  

Go语言【数据结构】指针的更多相关文章

  1. 浅谈c语言的指针

    对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...

  2. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  3. C语言二重指针与malloc

    (内容主要源于网上,只是加入了些自己的剖析) 假设有一个二重指针: char **p; 同时有一个指针数组 char *name[4]; 如何引用p呢? 首先我们有程序代码如下 #include &l ...

  4. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  5. 为什么C/C++语言使用指针

    这是参加面试时,面试官问的一道开放性题目. 问题是:为什么C/C++语言使用指针? 这个问题一问出来,直接被面试官秒杀了,面试官大神,你怎么不按套路出牌啊? 说好的malloc和new的区别呢?说好的 ...

  6. C语言的指针变量

    C语言的指针变量 在C语言中,变量是固定范围的存储空间,它存储的是赋给他的值, 比如: ; /* 这里是定义一个整型变量a,并把12这个值存储在a的地址空间上 这个地址空间是系统随机分配的,对用户是透 ...

  7. Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  8. “对外部(局部)变量的访问”是C语言函数指针的最大弱点

    1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...

  9. go语言学习--指针的理解

    Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, fu ...

  10. C语言中指针占据内存空间问题

    以前一直有个疑问,指向不同类型的指针到底占用的内存空间是多大呢? 这个问题我多次问过老师,老师的答案是"指向不同类型的指针占据的内存空间大小不同",我一直很之一这个答案,今天我就做 ...

随机推荐

  1. 隐马尔科夫模型(Hidden Markov Models) 系列之四

    转自:http://blog.csdn.net/eaglex/article/details/6430389 前向算法(Forward Algorithm) 一.如果计算一个可观察序列的概率?   1 ...

  2. error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用

    出现如下错误: error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用 解决办法:

  3. flink Iterate迭代基本概念

    基本概念:在流中创建“反馈(feedback)”循环,通过将一个算子的输出重定向到某个先前的算子.这对于定义不断更新模型的算法特别有用. 迭代的数据流向:DataStream → IterativeS ...

  4. 集成学习 - Bagging

    认识 Bagging 的全称为 (BootStrap Aggregation), 嗯, 咋翻译比较直观一点呢, 就有放回抽样 模型训练? 算了, 就这样吧, 它的Paper是这样的: Algorith ...

  5. 定时调度之Quartz

    工作中我们经常碰到定时或者固定时间点去做一些事情,然后每天到时间点就会去做这样的事情,如果理解这样的场景,我们就要引入今天我们的主角Quartz,其实这个跟数据库的作业类似,但是不仅仅局限于数据库. ...

  6. 数据结构篇——平衡二叉树(AVL树)

    引入 上一篇写了二叉排序树,构建一个二叉排序树,如果构建序列是完全有序的,则会出现这样的情况: 显然这种情况会使得二叉搜索树退化成链表.当出现这样的情况,二叉排序树的查找也就退化成了线性查找,所以我们 ...

  7. 模型选择---KFold,StratifiedKFold k折交叉切分

    StratifiedKFold用法类似Kfold,但是他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同. 例子: import numpy as np from sklearn.m ...

  8. Python面试题(4)

    1.Python下多线程的限制以及多进程中传递参数的方式 Python多线程有个全局解释器锁,这个锁的意思是任一时间只能有一个线程运用解释器.并发不是并行. 多进程间同享数据,能够运用multipro ...

  9. destoon开发笔记-调取资讯标题图

    今天刚申请博客园的博客,申请速度挺快的.之前我的文章都是发在自己搭建的博客网站,但是是香港服务器,不想续费了,所以就关闭了.之前的数据也没有了,挺可惜了.不过既然加入博客园的大家庭,我就在这每天记录工 ...

  10. Nacos 学习资料

    资料 网址 官方网站 https://nacos.io/zh-cn/docs/what-is-nacos.html github https://github.com/alibaba/nacos 程序 ...