在python中,有一句話叫做一切皆對象,一切皆引用,因此在python中,其實不存在真正意義上的基礎數據類型,無論是列表,字符串,數值類型,實際上都是一個個類所產生的對象。這也是為什麼python中 整型 沒有長度限制,能夠無限大的原因。
也正因為python中一切皆對象,python 底層存儲值的方式,都是 變量名 -> 內存地址,內存地址-> 數據,這種引用傳遞的方式。
如果python沒有做任何處理,按理來說,不管是列表還是數字,字符串,修改值時,內存地址應該都是不變的。但是僅有集合,列表,字典三種類型數據修改值而內存地址不改變的數據類型,在python中稱為可變類型
但是,實際上,如果在python中如果修改的是 數值,字符串,元組,布爾類型的數據,值改變,內存地址也會跟著變,這一類在python中稱之為不可變類型數據
這一點,可以在函數傳參中,可以更加清楚的看出來,可變類型傳入,在函數內部名稱空內修改,全局的數據也會跟著修改,但是不可變類型,在內部空間修改,卻不會影響到全局變量
所以,其實在python中,這就很古怪,因此真正明白的人,都不會去說python函數傳參是引用傳遞,還是值傳遞,而是講的是一切皆引用,因此python作者才分出來可變與不可變類型。所以看到這,你就是明白人了
而在go中,兩者就有很好的區分。go中的數據類型可以分為值類型和引用類型兩大塊
值類型包括: 所有的整型、浮點型、bool型、string型、數組和struct類型
值類型的特點是變量直接存儲值,內存通常在 棧(stack) 中分配
引用類型包括: 指正、slice、map、chan、interface
引用類型的特點,變量存儲的是一個地址,這個地址對應的空間才真正存儲的數據,內存分配通常在 堆(heap) 上分配,當沒有任何變量引用這個地址的時候,該地址對應的數據空間會被GC回收 -> 這點和 python 不能說是一模一樣,只能說是 別無二樣
在 go 中,給函數傳參,如果參數類型是值類型,就會 copy 一份再傳入函數內部,如果是引用類型,就直接把參數傳入函數(也有可能都copy了,不過一個copy的值,一個copy的內存地址)
補充: 不論是在go中還是在python中,函數都是一等公民,能夠直接當做變量值傳遞給變量名。也可以當做函數參數使用