Go语言【数据结构】指针
指针
本章围绕字符串、数字、数组、切片、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语言【数据结构】指针的更多相关文章
- 浅谈c语言的指针
对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...
- C#委托与C语言函数指针及函数指针数组
C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...
- C语言二重指针与malloc
(内容主要源于网上,只是加入了些自己的剖析) 假设有一个二重指针: char **p; 同时有一个指针数组 char *name[4]; 如何引用p呢? 首先我们有程序代码如下 #include &l ...
- C语言函数指针基础
本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...
- 为什么C/C++语言使用指针
这是参加面试时,面试官问的一道开放性题目. 问题是:为什么C/C++语言使用指针? 这个问题一问出来,直接被面试官秒杀了,面试官大神,你怎么不按套路出牌啊? 说好的malloc和new的区别呢?说好的 ...
- C语言的指针变量
C语言的指针变量 在C语言中,变量是固定范围的存储空间,它存储的是赋给他的值, 比如: ; /* 这里是定义一个整型变量a,并把12这个值存储在a的地址空间上 这个地址空间是系统随机分配的,对用户是透 ...
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
- “对外部(局部)变量的访问”是C语言函数指针的最大弱点
1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...
- go语言学习--指针的理解
Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, fu ...
- C语言中指针占据内存空间问题
以前一直有个疑问,指向不同类型的指针到底占用的内存空间是多大呢? 这个问题我多次问过老师,老师的答案是"指向不同类型的指针占据的内存空间大小不同",我一直很之一这个答案,今天我就做 ...
随机推荐
- 详解Vue中的虚拟DOM
摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...
- unity点击按钮弹出操作提示界面
1.首先在相应的位置添加一个(UGUI控件)image,在image下添加文本框和按钮设计弹出框内容如图: 2.新建C#脚本UITips using System.Collections; using ...
- 使用Python3导出MySQL查询数据
整理个Python3导出MySQL查询数据d的脚本. Python依赖包: pymysql xlwt Python脚本: #!/usr/bin/env python # -*- coding: utf ...
- poi坑点(springboot)
工作上需要写了一个将数据库数据生成excel表的接口,在此过程中遇到了一些坑点,现在此纪录 PS:一部分可能是因为我没用明白 1. 样式问题 自动调整尽量不要使用,部分列留白过多,空列列宽过窄,可能是 ...
- Linux系统运行模式介绍
Linux运行模式 自由服务,即不需要用户独立去安装的软件服务,而是在系统安装好之后就可以直接使用的服务(内置服务). 运行模式也称为运行级别,属于linux的自有服务. 运行模式可以理解为一旦你开机 ...
- Html快速上手
Html 概述 HTML文档 Doctype Meta Title Link Style Script 常用标签 各种符号 p 和 br a 标签 H 标签 select input:checkbox ...
- python平台下实现xgboost算法及输出的解释
python平台下实现xgboost算法及输出的解释 1. 问题描述 近来, 在python环境下使用xgboost算法作若干的机器学习任务, 在这个过程中也使用了其内置的函数来可视化树的结果, ...
- 使用adb 命令(atrace)抓起systrace的方法。
adb shell atrace -c -b --async_start -z gfx 1. 执行查看adb shell atrace 功能 atrace --h atrace: invalid op ...
- robotframework连接mysql
1.安装mysql数据库,并启动,创建数据库test及user表(可以自定义) 2.配置robotframework环境加载DatabaseLibrary 3.安装pymysql,下载地址:https ...
- ESA2GJK1DH1K基础篇: Android连接MQTT简单的Demo
题外话 我老爸也问我物联网发展的趋势是什么!!!!!! 我自己感觉的:(正在朝着 "我,机器人" 这部电影的服务器方向发展) 以后的设备都会和服务器交互,就是说本地不再做处理,全部 ...