成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何理解 Golang 的參數傳遞都是值傳遞?

存儲 存儲設備
在 Golang 中函數之間傳遞變量時總是以值的方式傳遞的,無論是 int,string,bool,array 這樣的內置類型(或者說原始的類型),還是 slice,channel,map 這樣的引用類型,在函數間傳遞變量時,都是以值的方式傳遞,也就是說傳遞的都是值的副本。

在 Golang 中函數之間傳遞變量時總是以值的方式傳遞的,無論是 int,string,bool,array 這樣的內置類型(或者說原始的類型),還是 slice,channel,map 這樣的引用類型,在函數間傳遞變量時,都是以值的方式傳遞,也就是說傳遞的都是值的副本。

內置類型參數傳遞

內置類型傳遞的時候是值的副本,這個好理解,隨便舉個例子:

  1. package main 
  2.   
  3. import ( 
  4.     "fmt" 
  5.   
  6. func main() { 
  7.     num := 10 
  8.     num2 := increase(num, 10) 
  9.     fmt.Println(num2) 
  10.   
  11. func increase(num intadd intint { 
  12.     return num + add 

[[212146]]

這里 num 傳入 increase 函數,是拷貝值的副本,并且返回一個新的值。假設 num 是一個很大的數組,那么傳遞給函數的就是這個很大數組的拷貝。(這樣很浪費內存,真實情況如果要傳一個很大的數組,應該傳遞數組的指針)

引用類型的參數傳遞

引用類型的參數傳遞也是值的拷貝。

例子:

  1. package main 
  2.   
  3. import ( 
  4.     "fmt" 
  5.   
  6. func main() { 
  7.     slice1 := []string{"zhang""san"
  8.     modify(slice1) 
  9.     fmt.Println(slice1) 
  10.   
  11. func modify(data []string) { 
  12.     data = nil 

運行結果:

[zhang san]

這個例子證明了作為引用類型的切片,參數傳遞不是傳的引用,而是傳的值,如果是傳的引用,那么函數對它的修改會受到影響,而這里切片內容并沒有改變成 nil.

但是有一個例子比較誤導人,我們看一看:

  1. package main 
  2.   
  3. import ( 
  4.     "fmt" 
  5.   
  6. func main() { 
  7.     slice1 := []string{"zhang""san"
  8.     modify(slice1) 
  9.     fmt.Println(slice1) 
  10.   
  11. func modify(data []string) { 
  12.     data[1] = "si" 

運行結果:

[zhang si]

這里為什么改變了切片的內容呢?

什么是標頭?

搞清楚這個問題,首先要知道什么是“標頭”這個概念?引用《Go語言實踐》中的一段話:

Go 語言里的引用類型有如下幾個:切片、映射、通道、接口和函數類型。當聲明上述類型的變量時,創建的變量被稱作標頭(header)值。從技術細節上說,字符串也是一種引用類型。每個引用類型創建的標頭值是包含一個指向底層數據結構的指針。因為標頭值是為復制而設計的,所以永遠不需要共享一個引用類型的值。標頭值里包含一個指針,因此通過復制來傳遞一個引用類型的值的副本,本質上就是在共享底層數據結構。

總而言之,引用類型在函數傳遞的時候,是值傳遞,只不過這里的“值”指的是標頭值。

我們分別打印這個切片變量傳參前后的指針地址,和傳參前后切片中元素的指針地址:

  1. package main 
  2.   
  3. import ( 
  4.     "fmt" 
  5.   
  6. func main() { 
  7.     slice1 := []string{"zhang""san"
  8.     fmt.Printf("%p\n", &slice1) 
  9.     fmt.Printf("%p\n", &slice1[1]) 
  10.     modify(slice1) 
  11.     fmt.Println(slice1) 
  12.   
  13. func modify(data []string) { 
  14.     fmt.Printf("%p\n", &data) 
  15.     fmt.Printf("%p\n", &data[1]) 
  16.     data[1] = "si" 

運行結果:

0xc42000a060

0xc42000a090

0xc42000a0a0

0xc42000a090

這再次證明了切片傳遞的不是指針地址,因為變量前后地址不同。

這也證明了切片的參數傳遞的是傳值的形式,具體是傳標頭值的拷貝,因為指向元素的指針地址相同。

責任編輯:武曉燕 來源: 小談博客
相關推薦

2015-09-08 10:16:41

Java參數按值傳遞

2012-02-21 14:04:15

Java

2025-02-12 10:51:51

2022-07-29 08:05:31

Java值傳遞

2019-04-17 13:48:19

JavaScript前端傳遞

2009-08-17 14:48:44

Java參數傳遞機制

2024-09-04 01:36:51

Java對象傳遞

2009-06-09 21:54:26

傳遞參數JavaScript

2011-03-25 13:44:28

Java值傳遞

2025-04-02 12:00:00

開發日志記錄Python

2016-09-18 19:07:33

Java值傳遞引用傳遞

2023-11-15 09:14:27

Java值傳遞

2023-03-29 23:23:00

MyBatis參數框架

2010-09-10 09:55:13

SQL參數變量

2012-06-19 14:35:24

JSPJava亂碼

2025-01-17 10:52:26

定義函數編程Python

2024-09-19 20:59:49

2009-06-24 13:14:11

URL來傳遞參數JSF

2009-12-17 17:04:09

Ruby函數參數傳遞

2020-09-02 08:00:51

Java引用傳遞值傳遞
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 视频一区在线观看 | 国产极品粉嫩美女呻吟在线看人 | 久久久国产一区 | 久久久久国产精品人 | 九九热精 | 亚洲视频在线播放 | 亚洲一区精品视频 | 爱高潮www亚洲精品 中文字幕免费视频 | 天天爱天天操 | 成人午夜网站 | www.日韩| 成年人免费网站 | 成人精品一区二区 | 日韩精品久久久 | www.日日干 | 久久久久久久久久久久久久国产 | av在线三级 | 国产成人高清视频 | 伊人青青久久 | 欧美日韩视频 | 中文字幕av高清 | www97影院 | 国产精品自拍视频网站 | 91av在线影院 | 91精品国产色综合久久不卡98 | 欧美在线一区二区三区 | 在线日韩精品视频 | 99爱在线视频 | 不卡一区二区在线观看 | 国产高清精品一区二区三区 | 911影院 | 波多野结衣中文字幕一区二区三区 | 亚洲天堂一区二区 | 欧美精品一区二区三区在线播放 | 在线看片网站 | 九九热在线视频免费观看 | 成人午夜看片 | 国产丝袜一区二区三区免费视频 | 国产精品久久久久久久免费观看 | 日韩在线播放一区 | 中文字幕日韩一区 |