Golang系列(五)之Golang指標
1. 指標的概念
概念 | 說明 |
---|---|
變數 | 是一種佔位符,用於引用計算機的記憶體地址。可理解為記憶體地址的標籤 |
指標 | 表示記憶體地址,表示地址的指向。指標是一個指向另一個變數記憶體地址的值 |
& | 取地址符,例如:{指標}:=&{變數} |
* | 取值符,例如:{變數}:=*{指標} |
2. 記憶體地址說明
2.1. 記憶體定義
計算機的記憶體 RAM 可以把它想象成一些有序的盒子,一個接一個的排成一排,每一個盒子或者單元格都被一個唯一的數字標記依次遞增,這個數字就是該單元格的地址,也就是記憶體的地址。
硬體角度
邏輯角度:記憶體是一塊具備隨機訪問能力,支援讀寫操作,用來存放程式及程式執行中產生的資料的區域。
概念 | 比喻 |
---|---|
記憶體 | 一層樓層 |
記憶體塊 | 樓層中的一個房間 |
變數名 | 房間的標籤,例如:總經理室 |
指標 | 房間的具體地址(門牌號),例如:總經理室地址是2樓201室 |
變數值 | 房間裡的具體儲存物 |
指標地址 | 指標的地址:儲存指標記憶體塊的地址 |
2.2. 記憶體單位和編址
2.2.1. 記憶體單位
單位 | 說明 |
---|---|
位(bit) | 計算機中最小的資料單位,每一位的狀態只能是0或1 |
位元組(Byte) | 1Byte=8bit,是記憶體基本的計量單位 |
字 | “字”由若干個位元組構成,字的位數叫字長,不同檔次的機器有不同的字長 |
KB | 1KB=1024Byte,即1024個位元組 |
MB | 1MB=1024KB |
GB | 1GB=1024MB |
2.2.2. 記憶體編址
計算機中的記憶體按位元組編址,每個地址的儲存單元可以存放一個位元組的資料,CPU通過記憶體地址獲取指令和資料,並不關心這個地址所代表的空間在什麼位置,記憶體地址和地址指向的空間共同構成了一個記憶體單元。
2.2.3. 記憶體地址
記憶體地址通常用16進位制的資料表示,例如0x0ffc1。
3.變數與指標運算理解
編寫一段程式,檢索出值並存儲在地址為 200 的一個塊記憶體中,將其乘以 3,並將結果儲存在地址為 201 的另一塊記憶體中
3.1.本質
- 檢索出記憶體地址為 200 的值,並將其儲存在 CPU 中
- 將儲存在 CPU 中的值乘以 3
- 將 CPU 中儲存的結果,寫入地址為 201 的記憶體塊中
3.2.基於變數的理解
- 獲取變數 a 中儲存的值,並將其儲存在 CPU 中
- 將其乘以 3
- 將結果儲存在變數 b 中
var a = 6
var b = a * 3
3.3.基於指標的理解
func main() {
a := 200
b := &a
*b++
fmt.Println(a)
}
以上函式對a進行+1操作,具體理解如下:
1.a:=200
2. b := &a
3. *b++
4. 指標的使用
4.1. 方法中的指標
方法即為有接受者的函式,接受者可以是型別的例項變數或者是型別的例項指標變數。但兩種效果不同。
1、型別的例項變數
func main(){
person := Person{"vanyar", 21}
fmt.Printf("person<%s:%d>\n", person.name, person.age)
person.sayHi()
person.ModifyAge(210)
person.sayHi()
}
type Person struct {
name string
age int
}
func (p Person) sayHi() {
fmt.Printf("SayHi -- This is %s, my age is %d\n",p.name, p.age)
}
func (p Person) ModifyAge(age int) {
fmt.Printf("ModifyAge")
p.age = age
}
//輸出結果
person<vanyar:21>
SayHi -- This is vanyar, my age is 21
ModifyAgeSayHi -- This is vanyar, my age is 21
儘管 ModifyAge 方法修改了其age欄位,可是方法裡的p是person變數的一個副本,修改的只是副本的值。下一次呼叫sayHi方法的時候,還是person的副本,因此修改方法並不會生效。
即例項變數的方式並不會改變接受者本身的值。
2、型別的例項指標變數
func (p *Person) ChangeAge(age int) {
fmt.Printf("ModifyAge")
p.age = age
}
Go會根據Person的示例型別,轉換成指標型別再拷貝,即 person.ChangeAge會變成 (&person).ChangeAge。
指標型別的接受者,如果例項物件是值,那麼go會轉換成指標,然後再拷貝,如果本身就是指標物件,那麼就直接拷貝指標例項。因為指標都指向一處值,就能修改物件了。
5. 零值與nil(空指標)
變數宣告而沒有賦值,預設為零值,不同型別零值不同,例如字串零值為空字串;
指標宣告而沒有賦值,預設為nil,即該指標沒有任何指向。當指標沒有指向的時候,不能對(*point)進行操作包括讀取,否則會報空指標異常。
func main(){
// 宣告一個指標變數 aPot 其型別也是 string
var aPot *string
fmt.Printf("aPot: %p %#v\n", &aPot, aPot) // 輸出 aPot: 0xc42000c030 (*string)(nil)
*aPot = "This is a Pointer" // 報錯: panic: runtime error: invalid memory address or nil pointer dereference
}
解決方法即給該指標分配一個指向,即初始化一個記憶體,並把該記憶體地址賦予指標變數,例如:
// 宣告一個指標變數 aPot 其型別也是 string
var aPot *string
fmt.Printf("aPot: %p %#v\n", &aPot, aPot) // 輸出 aPot: 0xc42000c030 (*string)(nil)
aPot = &aVar
*aPot = "This is a Pointer"
fmt.Printf("aVar: %p %#v \n", &aVar, aVar) // 輸出 aVar: 0xc42000e240 "This is a Pointer"
fmt.Printf("aPot: %p %#v %#v \n", &aPot, aPot, *aPot) // 輸出 aPot: 0xc42000c030 (*string)(0xc42000e240) "This is a Pointer"
或者通過new開闢一個記憶體,並返回這個記憶體的地址。
var aNewPot *int
aNewPot = new(int)
*aNewPot = 217
fmt.Printf("aNewPot: %p %#v %#v \n", &aNewPot, aNewPot, *aNewPot) // 輸出 aNewPot: 0xc42007a028 (*int)(0xc42006e1f0) 217
6. 總結
- Golang提供了指標用於操作資料記憶體,並通過引用來修改變數。
- 只宣告未賦值的變數,golang都會自動為其初始化為零值,基礎資料型別的零值比較簡單,引用型別和指標的零值都為nil,nil型別不能直接賦值,因此需要通過new開闢一個記憶體,或者通過make初始化資料型別,或者兩者配合,然後才能賦值。
- 指標也是一種型別,不同於一般型別,指標的值是地址,這個地址指向其他的記憶體,通過指標可以讀取其所指向的地址所儲存的值。
- 函式方法的接受者,也可以是指標變數。無論普通接受者還是指標接受者都會被拷貝傳入方法中,不同在於拷貝的指標,其指向的地方都一樣,只是其自身的地址不一樣。
相關推薦
Golang系列(五)之Golang指標
1. 指標的概念 概念 說明 變數 是一種佔位符,用於引用計算機的記憶體地址。可理解為記憶體地址的標籤 指標 表示記憶體地址,表示地址的指向。指標是一個指向另一個變數記憶體地址的值 & 取地址符,
Golang系列(二)之面向物件程式設計
面向物件程式設計: 把一組資料結構和處理它們的方法組成物件(object),把相同行為的物件歸納為類(class),通過類的封裝(encapsulation)隱藏內部細節,通過繼承(inheritance)實現類的特化(specialization)[方法的重寫,
Golang系列(一)之基礎篇
一、初識Go語言(一)概述一個在語言層面實現了併發機制的類C通用型程式語言。(二)Go關鍵字(25個)類別關鍵字說明程式宣告package,import包的宣告和匯入宣告與定義var,const變數和常量的宣告type用於定義型別複合資料型別struct定義結構體,類似java中的classinterface
【轉】Spring MVC系列(五)之自定義數據綁定---HandlerMethodArgumentResolver
開閉 src pat 獲取參數 mvc .net 定義 開閉原則 淺析 介紹 前面幾節我們介紹了Spring MVC的幾種常見的數據綁定的方法,可以靈活地獲取用戶請求中的參數,例如@PathVariable,@ModelAttribute,@RequestPar
Mysql資料庫優化系列(五)------索引優化策略之面試題
實驗: Type:range 此處使用上了範圍索引 Key_len:12/3=4列 使用到了索引c1,c2,c3,c4.解析:因為order by c3是有序的,所以c3,c4也用到了索引 上圖用到了c1,c2,c3,order by有序,可以利用索引。 上圖
程式設計師之網路安全系列(五):數字證書以及12306的證書問題
系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 中間人攻擊 上面
重學Golang系列(一): 深入理解 interface和reflect
前言 interface(即介面),是Go語言中一個重要的概念和知識點,而功能強大的reflect正是基於interface。本文即是對Go語言中的interface和reflect基礎概念和用法的一次梳理,也算是我階段學習的總結,以期溫故而知新。 interface(介面) 定義 在Go語言中,如果自定義型
資料探勘入門系列教程(五)之Apriori演算法Python實現
資料探勘入門系列教程(五)之Apriori演算法Python實現載入資料集獲得訓練集頻繁項的生成生成規則獲得support獲得confidence獲得Lift進行驗證總結參考 資料探勘入門系列教程(五)之Apriori演算法Python實現 在上一篇部落格中,我們介紹了Apriori演算法的演算法流
python系列(五)centos6.x中部署多個python版本
python pyenv centos6.x virtualenv 博主QQ:819594300博客地址:http://zpf666.blog.51cto.com/有什麽疑問的朋友可以聯系博主,博主會幫你們解答,謝謝支持!使用pyenv+virtualenv方式部署python多版本pyenv
bfzwjeqjSpriNgMc學習系列(3)之url
ref htm 學習 pri blank url lan get 系列 bfzwjeqjSpriNgMc學習系列(3)之url χ絳 bfzwjeqjSpriNgMc學習系列(3)之urlbfzwjeqjSpriNgMc學習系列(3)之url
python爬蟲從入門到放棄(五)之 正則的基本使用
語言 代碼例子 name 添加 iter ima 制表符 imp things 什麽是正則表達式 正則表達式是對字符串操作的一種邏輯公式,就是 事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符”,這個“規則字符” 來表達對字符的一種過濾邏輯。 正則並不是
mysql基礎(五)之pymysql
none set python 導入 char span import mysql pre pymysql模塊: pip3 install pymysql -i https://pypi.douban.com/simple Python模塊:對數據庫進行
源碼分析系列(五)x264_ratecontrol_dataflow
技術 stc 碼率控制 碼率 targe article nbsp target 緩沖區 http://www.cnblogs.com/xkfz007/articles/2616159.html 碼率控制部分關鍵函數 5.1 x264_ratecontrol_star
Windows Server 2012(單林、多樹、多站點)AD 部署系列(五)創建樹域
windows server 域 樹域 站點 多域環境 本章博文開始在BJ、SH、GZ站點為林bicionline.org 創建樹域控及調配的相關DNS等功能。網絡配置:1、為BJ站點ds04、SH站點pdc02和GZ站點ad02配置網絡, IP配置分別如下:(註:在創建域樹環境時,確
PHP系列(五)PHP字符串處理
php字符串處理 php字符串處理1、字符串的處理方式(分割匹配找查替換)//聲明一個關聯數組,數組名為$lamp, 成員有4個$lamp = array( ‘os‘=>‘Linux‘,‘webserver‘ =>‘Apache‘, ‘db‘=>‘MySQL‘, ‘language‘=>
Maven(五)之Maven配置阿裏雲鏡像飛快下jar包
png 技術分享 jar包 世界 包導入 ont 全世界 需要 XML 用過Maven的人都知道Maven對於依賴的管理讓我們程序員從此遠離了自己去在項目中把需要的jar包導入到項目中,但是因為中央倉庫是在國外的,所以在我們從中央倉庫下載依賴的時候, 我們發現下載速度真的
JavaWeb(五)之JSTL標簽庫
ron 數據庫連接 導入jar 作用域 .text 字符串操作 p標簽 異常 讀取 前言 前面介紹了EL表達式,其實EL表達式基本上是和JSTL核心標簽庫搭配一起使用才能發揮效果的。接下來讓我們一起來認識一下吧! 在之前我們學過在JSP頁面上為了不使用腳本,所以
Python操作rabbitmq系列(五):根據主題分配消息
method type 同時 elephant com .info err 現在 bin 接著上一章,使用exchange_type=‘direct‘進行消息傳遞。這樣消息會完全匹配後發送到對應的接收端。現在我們想幹這樣一件事: C1獲取消息中包含:orange內容的消息,
Java常用類(五)之集合工具類Collections
可變集合 並發 nts oid element 出現的次數 ole 最小 概述 前言 Java提供了一個操作Set、List和Map等集合的工具類:Collections,該工具類提供了大量方法對集合進行排序、查詢和修改等操作, 還提供了將集合對象置為不可
Vue入門系列(五)Vue實例詳解與生命周期
auto res context mode parent all from bool silent 【入門系列】 【本文轉自】 http://www.cnblogs.com/fly_dragon Vue的實例是Vue框架的入口,其實也就是前端的ViewM