您當前的位置:首頁 > 文化

GO不能改變陣列值,為什麼陣列賦值還是值複製?

作者:由 知乎使用者 發表于 文化時間:2018-11-04

GO不能改變陣列值,為什麼陣列賦值還是值複製?知乎使用者2018-11-06 09:48:40

先問是不是, 再問為什麼

package

main

import

“fmt”

func

main

()

{

a

:=

。。。

int

{

1

2

3

}

a

1

=

33

fmt

Println

a

}

修改了問題。 你隨便一搜不就有了。

Go中Map原地修改value

GO不能改變陣列值,為什麼陣列賦值還是值複製?知乎使用者2018-11-07 02:18:23

深夜回答一波,golang裡面就沒有引用傳遞一說,設計的時候就沒有設計引用,引數的傳遞都是值複製,包括string ,struct slice 都是,只有一種情況,就是閉包函式中引數的傳遞是引用,具體分析等我上程式碼

GO不能改變陣列值,為什麼陣列賦值還是值複製?知乎使用者2018-11-08 15:02:24

Go中有一個概念叫做

可定址性

https://golang。org/ref/spec#Address_

For an operand x of type T, the address operation &x generates a pointer of type *T to x。 The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array。 As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal。 If the evaluation of x would cause a run-time panic, then the evaluation of &x does too。

For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x。 If x is nil, an attempt to evaluate *x will cause a run-time panic。

通俗的講就是能否透過&運算子找到對應的記憶體地址。

array/slice的元素是可定址的(可以透過&arr[index]找到對應元素的記憶體地址),所以可以直接操作元素的值;

map的值是不可定址的(無法透過&map[key]找到key對應的value的記憶體地址,但如果v:=map[key]; &v就是可定址的,因為所有變數都是可定址的),所以不可以直接操作值裡面的值;

如果想實現修改的目的,把map的值換成指標即可,要是還不能理解,就這麼想,編譯器找不到map[key]對應value的記憶體地址,那麼我們就讓value本身就是一個地址(指標)好了,按照題主的程式碼,即

//map

b

:=

map

int

*

test

{

1

&

test

{

1

},

2

&

test

{

2

},

3

&

test

{

3

}}

b

1

]。

a

=

33

// ok

fmt

Println

b

1

])

GO不能改變陣列值,為什麼陣列賦值還是值複製?與你曖昧的不是我2018-11-13 14:08:23

Go全是值複製

GO不能改變陣列值,為什麼陣列賦值還是值複製?資料猿2021-12-10 11:42:29

1。Array概念

陣列:是同一種資料型別的固定長度的序列。

陣列定義:var a [len]int,比如:var a [5]int,陣列長度必須是常量,且是型別的組成部分。一旦定義,長度不能變。

長度是陣列型別的一部分,因此,var a[5] int和var a[10]int是不同的型別。

陣列可以透過下標進行訪問,下標是從0開始,最後一個元素下標是:len-1

for i := 0; i < len(a); i++ {

}

for index, v := range a {

}

訪問越界,如果下標在數組合法範圍之外,則觸發訪問越界,會panic

陣列是值型別,賦值和傳參會複製整個陣列,而不是指標。因此改變副本的值,不會改變本身的值。

支援 “==”、“!=” 運算子,因為記憶體總是被初始化過的。

指標陣列 [n]*T,陣列指標 *[n]T。

2。一維陣列

全域性:

var arr0 [5]int = [5]int{1, 2, 3}

var arr1 = [5]int{1, 2, 3, 4, 5}

var arr2 = [。。。]int{1, 2, 3, 4, 5, 6}

var str = [5]string{3: “hello world”, 4: “tom”}

區域性:

a := [3]int{1, 2} // 未初始化元素值為 0。

b := [。。。]int{1, 2, 3, 4} // 透過初始化值確定陣列長度。

c := [5]int{2: 100, 4: 200} // 使用索引號初始化元素。

d := [。。。]struct {

name string

age uint8

}{

{“user1”, 10}, // 可省略元素型別。

{“user2”, 20}, // 別忘了最後一行的逗號。

}

3。多維陣列

全域性

var arr0 [5][3]int

var arr1 [2][3]int = [。。。][3]int{{1, 2, 3}, {7, 8, 9}}

區域性:

a := [2][3]int{{1, 2, 3}, {4, 5, 6}}

b := [。。。][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 緯度不能用 “。。。”。

標簽: int  陣列  var  map  定址