Go Frequently Asked Questions (FAQ)
When are function parameters passed by value?
Как и во всех языках в семье C, все в Go передается б y значение. То есть, функция всегда получает копию вещи, которая прошла , как если бы был оператор присваивания, присваивающий этому параметру значение . Например, передача значения int функции делает копию int, и передача значения указателя делает копию указателем, но не данными, на которые указывает.
Should I define methods on values or pointers?
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
Для программистов непривычных к указателям, различие между эти два примера могут сбивать с толку, но ситуация на самом деле очень просто. При определении метода для типа приемник (s в примерах ) ведет себя точно так же, как если бы это был аргумент метода .Независимо от того, определять ли получатель в качестве значения или как указатель тот же вопрос, то как должен быть аргумент функции значением или указателем. Существует несколько соображений.
Во-первых, и, самое главное, нужен ли метод для изменения приемника ? Если это так, приемник должен быть указателем. (Ломтики и карты действуют как ссылки, поэтому их рассказ немного более тонкий, но для экземпляр, чтобы изменить длину среза в методе, получатель должен по-прежнему быть указателем.) В приведенных выше примерах, если pointerMethod изменяет поля s, вызывающий будет видеть эти изменения, но valueMethod - , вызываемый с копией аргумента вызывающего абонента (это определение , передающее значение), поэтому изменения, которые он делает, будут невидимы для вызывающего.
Кстати, приемники-указатели идентичны ситуации в Java, , хотя в Java указатели скрыты под обложками; это Go's Ценностные приемники, которые являются необычными.
Во-вторых, рассмотрение эффективности. Если приемник большой, например, большой структуры, будет гораздо дешевле использовать указатель .
Следующая последовательность. Если некоторые из методов этого типа должны иметь указатели-указатели, то остальное тоже должно быть, поэтому набор методов равен , независимо от того, как используется этот тип. Подробные сведения см. В разделе наборы меток .
Для таких типов, как основные типов, ломтики и малые структуры, значение приемника очень дешево, поэтому, если семантика методы требует указателя, значение приемник является эффективным и ясно.
Подход к указателям языка Go немного запутан. В Go вы определяете приемник метода, чтобы указать, к какой структуре присоединяется определенная функция, чтобы он мог быть вызван как метод. –