七叶笔记 » golang编程 » golang中的传值或传引用

golang中的传值或传引用

golang 数据类型

按数据类别有以下几种数据类型:

  • 基础类型:如布尔类型(bool),数字类型(int,int64,uint32,float64,complex64…),字符串类型(string), 数组类型([4]int, [8]string
  • 派生类型: 指针类型(Pointer),结构化类型(struct), Channel 类型, 函数类型(f),切片类型,接口类型(interface), Map 类型。

按存储方式也有两大类数据类型:

  • 值类型,也叫基本数据类型:数值类型、bool、string、数组、struct 结构体
  • 引用数据类型:指针、slice 切片、管道 chan、map、以及 interface

值类型:变量直接存储值。值类型的数据存储在栈内存空间中,栈在函数调f返回后,内存会被释放。

引用类型:变量存储的是一个地址,这个地址存储最终的值。引用数据类型的数据存储在堆内存空间中,通过 GC 回收。

基础类型为值传递

函数调用时申明的基础类型均为值传递,如int,string,数组等,数据传入函数后会重新copy一份,函数内的修改不会影响外面的变量,外部变量的修改也不会影响函数类的变量。

func main () {

myvar := [ 4 ] string {” test0 “, ” test1 “, ” test3 “, ” test4 “}

go Test (myvar)

for i := 1 ; i <= 2 ; i ++ {

myvar[i] = loop + strconv. Itoa (i)

fmt. Printf (” Main Addr[ %p ]=> %v \n “, & myvar, myvar)

time. Sleep (time.Second * 2 )

}

}

func Test (myVar [ 4 ] string ) {

for {

fmt. Printf (” Type[ %T ]=> %v \n “, myVar, myVar)

time. Sleep (time.Second * 1 )

}

}

struct传值或传引用

struct默认是值传递,只有申明为结构指针时才是引用传递,如通过修改如下程序可验证

type ConnFields struct {

Port int

Num int

}

// struct传引用

func main () {

myField := & ConnFields{ 5200 , 1 }

go Test (myField)

for i := 1 ; i <= 2 ; i ++ {

myField.Port += i

fmt. Printf (” Main Addr[ %p ]=> {port: %d , id: %d } \n “,

myField, myField.Port, myField.Num)

time. Sleep (time.Second * 2 )

}

}

func Test (myField *ConnFields) {

for {

fmt. Printf (” Func Addr[ %p ] ==>{port: %d , id: %d } \n “, myField, myField.Port, myField.Num)

time. Sleep (time.Second * 1 )

}

}

map类型

map类型是传引用

func main () {

myMap := make ( map [ int ] string )

myMap[ 0 ] = test0

go Test (myMap)

for i := 1 ; i <= 2 ; i ++ {

myMap[i] = loop + strconv. Itoa (i)

fmt. Printf (” Main Addr[ %p ]=> %v \n “, myMap, myMap)

time. Sleep (time.Second * 2 )

}

}

func Test (myMap map [ int ] string ) {

for {

fmt. Printf (” Func Addr[ %p ]=> %v \n “, myMap, myMap)

time. Sleep (time.Second * 1 )

}

}

slice(切片)

切片调用时传递的是引用

func main () {

mySlice := [] string {” test0 “, ” test1 “, ” test3 “, ” test4 “}

go Test (mySlice)

for i := 1 ; i <= 2 ; i ++ {

mySlice[i] = loop + strconv. Itoa (i)

fmt. Printf (” Main Addr[ %p ]=> %v \n “, mySlice, mySlice)

time. Sleep (time.Second * 2 )

}

}

func Test (mySlice [] string ) {

for {

fmt. Printf (” Func Addr[ %p ]=> %v \n “, mySlice, mySlice)

time. Sleep (time.Second * 1 )

}

}

interface{}接口类型

当申明函数变量为interface{}类型时,具体是值传递还是引用传递依赖传入变量自身

如下面的测试代码,当传入参数为数组时是值传递,当传入参数是切片时为引用传递

func main () {

myvar := [ 4 ] string {” test0 “, ” test1 “, ” test3 “, ” test4 “}

go Test (myvar)

for i := 1 ; i <= 2 ; i ++ {

myvar[i] = loop + strconv. Itoa (i)

fmt. Printf (” Main Addr[ %p ]=> %v \n “, & myvar, myvar)

time. Sleep (time.Second * 2 )

}

}

func Test (myVar interface {}) {

for {

fmt. Printf (” Type[ %T ]=> %v \n “, myVar, myVar)

time. Sleep (time.Second * 1 )

}

}

相关文章