GO不能改變陣列值,為什麼陣列賦值還是值複製?
先問是不是, 再問為什麼
package
main
import
(
“fmt”
)
func
main
()
{
a
:=
[
。。。
]
int
{
1
,
2
,
3
}
a
[
1
]
=
33
fmt
。
Println
(
a
)
}
修改了問題。 你隨便一搜不就有了。
Go中Map原地修改value
深夜回答一波,golang裡面就沒有引用傳遞一說,設計的時候就沒有設計引用,引數的傳遞都是值複製,包括string ,struct slice 都是,只有一種情況,就是閉包函式中引數的傳遞是引用,具體分析等我上程式碼
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全是值複製
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 緯度不能用 “。。。”。