Ответ
В Go все аргументы в функции передаются исключительно по значению (pass by value). Это означает, что функция всегда получает копию передаваемой переменной, а не саму переменную.
Однако поведение зависит от типа данных:
Простые типы (int, string, bool, struct):
Создается полная копия значения. Изменения этой копии внутри функции не влияют на исходную переменную.Ссылочные типы (слайсы, мапы, каналы, указатели):
Копируется не сам базовый массив данных или структура, а значение-дескриптор (для слайсов, мап) или адрес в памяти (для указателей). Этот дескриптор или указатель по-прежнему ссылается на ту же самую область памяти, что и оригинал.- Слайсы и мапы: Изменение элементов слайса или мапы внутри функции будет видно снаружи, так как копия дескриптора указывает на тот же базовый массив данных.
- Указатели: Изменение значения, на которое указывает указатель, также будет видно снаружи.
Пример для наглядности:
package main
import "fmt"
// Принимает копию int. Изменения не видны снаружи.
func modifyValue(val int) {
val = 100
}
// Принимает копию указателя. Изменения по указателю видны снаружи.
func modifyPointer(ptr *int) {
*ptr = 100
}
// Принимает копию дескриптора слайса. Изменения элементов видны снаружи.
func modifySlice(slice []int) {
slice[0] = 100
}
func main() {
// Простой тип
num := 10
modifyValue(num)
fmt.Println("num после modifyValue:", num) // Вывод: 10
// Указатель
modifyPointer(&num)
fmt.Println("num после modifyPointer:", num) // Вывод: 100
// Слайс
s := []int{1, 2, 3}
modifySlice(s)
fmt.Println("slice после modifySlice:", s) // Вывод: [100 2 3]
}
Вывод: Хотя технически передача всегда идет по значению, для ссылочных типов эффект похож на передачу по ссылке, так как копируется не сама структура данных, а указатель на нее.