国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - Go 值傳遞與引用傳遞的方法

Go 值傳遞與引用傳遞的方法

2020-05-23 11:59chencanxin Golang

這篇文章主要介紹了Go 值傳遞與引用傳遞的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

問題引入

  • 什么時候選擇 T 作為參數類型,什么時候選擇 *T 作為參數類型?
  • [ ] T 是傳遞的指針還是值?選擇 [ ] T 還是 [ ] *T ?
  • 哪些類型復制和傳遞的時候會創建副本?
  • 什么情況下會發生副本創建?

T 和 *T 當做函數參數時都是傳遞它的副本

先看傳 T 的情況:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type user struct {
  id int
  name string
}
 
func passByValue(_u user){
  _u.id++
  _u.name="jack"
 
  // when printing structs, the plus flag (%+v) adds field names
  fmt.Printf("_u 值:%+v;地址:%p; \n",_u,&_u)
}
 
func exp2(){
  u:=user{1,"peter"}
  fmt.Printf("原始 u 值:%+v; 地址: %p;\n",u,&u)
  passByValue(u)
  fmt.Printf("執行完函數后 u 值:%+v; 地址: %p;\n",u,&u)
}

執行 exp2 方法,輸出結果為:

Go 值傳遞與引用傳遞的方法

結果說明:

  • _u 是 u 的一份拷貝,地址不同
  • 函數內對參數的改變不影響原始的對象

再看傳 *T 的情況:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type user struct {
  id int
  name string
}
 
func passByPointer(_u *user){
  _u.id++
  _u.name="jack"
  fmt.Printf("_u 值:%+v ;u指向的地址:%p; u本身存放地址:%p; \n",*_u,_u,&_u)
}
 
func exp3(){
  u:=&user{1,"peter"}
  fmt.Printf("原始u 值:%+v; 指向的地址: %p;u本身存放地址: %p; \n",*u,u,&u)
  passByPointer(u)
  fmt.Printf("原始u 值:%+v; 指向的地址: %p;u本身存放地址: %p; \n",*u,u,&u)
}

執行 exp3 方法的輸出結果為:

Go 值傳遞與引用傳遞的方法

注意到,雖然參數 _u 仍然是 u 的一份拷貝對象,但是原始對象的值還是改變了。可以這么理解,因為 u 指針和 _u 指針都指向同一個對象,即 0xc0000484a0 地址上存放的對象,_u.name="jack"可以看做*(_u).name="jack,即取值后再改變值。

改變指針參數的地址

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type user struct {
  id int
  name string
}
 
func changeAddress(_u *user){
  _u=&user{2,"jack"}
  fmt.Printf("參數_u 值:%+v ;u指向的地址:%p; u本身存放地址:%p; \n",*_u,_u,&_u)
  return
}
 
func exp4(){
  u:=&user{1,"peter"}
  fmt.Printf("原始u 值:%+v; 指向的地址: %p;u本身存放地址: %p; \n",*u,u,&u)
  changeAddress(u)
  fmt.Printf("執行函數后 u 值:%+v; 指向的地址: %p;u本身存放地址: %p; \n",*u,u,&u)
}

輸出結果如下:

Go 值傳遞與引用傳遞的方法

注意,執行函數后 u 值沒有改變!改變了參數指向的地址,原來的對象肯定就不受影響了。

傳遞數組參數 vs 傳遞切片參數

?
1
2
3
4
5
6
7
8
9
10
11
func passSlice(_s []int){
  _s[0]=99
  fmt.Printf("_s 值:%v,地址:%p\n",_s,&_s)
}
 
func exp6(){
  s:=[]int{11,22,33,44}
  fmt.Printf("s 值:%v,地址:%p\n",s,&s)
  passSlice(s)
  fmt.Printf("執行函數后 s 值:%v,地址:%p\n",s,&s)
}

Go 值傳遞與引用傳遞的方法

對切片參數的修改會影響原來的切片。

再看傳遞數組

?
1
2
3
4
5
6
7
8
9
10
11
func passArray(_a [3]int){
  _a[0]=99
  fmt.Printf("_a 值:%v,地址:%p\n",_a,&_a)
}
 
func exp7(){
  a:=[3]int{22,33,44}
  fmt.Printf("a 值:%v,地址:%p\n",a,&a)
  passArray(a)
  fmt.Printf("執行函數后 a 值:%v,地址:%p\n",a,&a)
}

Go 值傳遞與引用傳遞的方法

對數組參數的修改并不會影響原來的切片。

總結會發生副本創建的情況

  • 賦值操作,如 u1:=u2。包括 slice,map,array 在初始化和按索引設置的時候都會創建副本
  • for-range循環也是將元素的副本賦值給循環變量,但注意一點,循環變量是被復用的,所以地址不會變
  • 將變量作為參數傳遞。但注意一點, slice,map,chanel 三者都和 *T 一樣,屬于引用傳遞,雖然是發生了副本創建,但是函數內對參數的值進行修改會影響原來的值。而數組不同于 slice,函數內對數組參數的值進行修改不會影響原來數組
  • 將返回值賦值給其它變量或者傳遞給其它的函數和方法
  • 字符串比較特殊,它的值不能修改,任何想對字符串的值做修改都會生成新的字符串
  • 函數也是一個指針類型,對函數對象的賦值只是又創建了一個對次函數對象的指針。

總結指針類型

  • slice
  • map
  • chanel
  • 函數

如何選擇 T 和 *T

對函數的參數或者返回值定義成 T 還是 *T 要考慮以下幾點:

  • 一般的判斷標準是看副本創建的成本和需求。
  • 如果不想變量被函數所修改,那么選擇類型 T
  • 如果變量是一個很大的struct或者數組,副本的創建相對會影響性能,這個時候要考慮使用*T,只創建新的指針
  • 對于函數作用域內的參數,如果定義成 T , Go 編譯器盡量將對象分配到棧上,而 *T 很可能會分配到對象上,這對垃圾回收會有影響

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://segmentfault.com/a/1190000018538664

 

延伸 · 閱讀

精彩推薦
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲精品国产电影 | 亚洲精品短视频 | 久久性色 | 亚洲网站在线 | 欧美精品在线一区二区三区 | 久久久亚洲综合 | 在线视频一区二区三区 | 亚洲国产精品久久久久婷婷老年 | 三区在线| 久久99精品久久久久久噜噜 | 久草 在线| 在线观看一区二区精品 | 黄色美女网站 | 91视频网页版 | 亚洲精品久久久 | 亚洲国产精品成人 | 欧美日本韩国一区二区 | 日韩国产| 亚洲午夜激情 | 国产福利一区二区三区四区 | 亚洲自拍中文 | 国产精品无码久久久久 | 日韩影片在线观看 | 91精品国产一区二区三区四区在线 | 欧美黄视频 | 激情综合网婷婷 | www.色.com | 午夜精品久久久久久久久久久久久 | 一区视频| 欧美午夜一区二区三区免费大片 | 亚洲成人一区二区在线观看 | 伊人五月 | 国产中文视频 | 中文字幕在线观看视频地址二 | 视频一区二区国产 | 免费久久久久 | 久久久婷婷 | 久久久国产一区二区三区 | 伊人网在线视频观看 | 精品久久久久久久久久久久久久 | 人人天天色|