2016-03-15 1 views
-1

В дороге я, кажется, есть два варианта:Должен ли я определять мои функции с указателем на структуру или просто на структуру?

foo := Thing{} 
foo.bar() 

foo := &Thing{} 
foo.bar() 


func (self Thing) bar() { 
} 

func (self *Thing) bar() { 
} 

Что такое лучший способ определить свои funcs с себя вещь или с самим собой * Вещь?

Редактировать: это не дубликат вопроса о методах и функциях. Этот вопрос имеет отношение к Thing и & Thing, и я думаю, что он достаточно разный, чтобы warrent это собственный url.

+2

Возможный дубликат [Что отличает функции и методы от Go?] (Http://stackoverflow.com/questions/8263546/whats-the-difference-of-functions-and-methods-in-go) – rkmax

+0

[«Указатели против значений в параметрах и возвращаемых значениях»] (http://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values/23551970#23551970) рассказывает о некоторые связанные с этим вопросы. – twotwotwo

ответ

1

Нет четкого ответа, но они совершенно разные. Когда вы не используете указатель, который вы передаете по значению, означает, что объект, на который вы его вызвали, будет неизменным (изменение копии), когда вы используете указатель, который вы передаете по ссылке '. Я бы сказал, что чаще вы используете сорт указателя, но он полностью ситуативен, нет лучшего способа.

Если вы посмотрите на различные рамки программирования/библиотеки классов, вы увидите множество примеров, в которых авторы сознательно выбрали действия по значению или ссылке. Например, в C# .NET это фундаментальное различие между структурой и классом и типами, такими как Guid и DateTime, были намеренно реализованы как структуры (тип значения). Опять же, я думаю, что указатель чаще всего является лучшим выбором (если вы просматриваете .NET, то почти все - это класс, ссылочный тип), но это определенно зависит от того, что вы хотите достичь с типом и/или тем, как вы хотите, чтобы потребители/другие разработчики взаимодействуют с ним. Возможно, вам нужно будет учитывать производительность и параллелизм (возможно, вы хотите, чтобы все было по стоимости, поэтому вам не нужно беспокоиться о параллельных операциях с типом, возможно, вам нужен указатель, потому что объем памяти объектов большой и копирование приведет к программа слишком медленная или чахоточная).

2

Посмотрите на этот пункт из the official FAQ:

Для программистов непривычных к указателям, различие между эти два примера могут сбивать с толку, но ситуация на самом деле очень просто. При определении метода для типа приемник (s в примерах ) ведет себя точно так же, как если бы это был аргумент метода . Независимо от того, определять ли получатель в качестве значения или как указатель тот же вопрос, то как должен быть аргумент функции значением или указателем. Существует несколько соображений.

Во-первых, и, самое главное, нужен ли метод для изменения приемника ? Если это так, приемник должен быть указателем. (Ломтики и карты действуют как ссылки, поэтому их рассказ немного более тонкий, но для экземпляр, чтобы изменить длину фрагмента в методе, получатель должен по-прежнему быть указателем.) В приведенных выше примерах, если pointerMethod изменяет поля s, вызывающий будет видеть эти изменения, но valueMethod - , вызываемый с копией аргумента вызывающего абонента (это определение , передающее значение), поэтому изменения, которые он делает, будут невидимы для вызывающего.

Кстати, приемники-указатели идентичны ситуации в Java, , хотя в Java указатели скрыты под обложками; это Go's Ценностные приемники, которые являются необычными.

Во-вторых, рассмотрение эффективности. Если приемник большой, например, большой структуры, будет гораздо дешевле использовать указатель .

Следующая последовательность. Если некоторые из методов этого типа должны иметь указатели-указатели, то остальное тоже должно быть, поэтому набор методов равен , независимо от того, как используется этот тип. Подробные сведения см. В разделе наборы меток .

Для таких типов, как основные типов, ломтики и малые структуры, значение приемника очень дешево, поэтому, если семантика методы требует указателя, значение приемник является эффективным и ясно.

Смежные вопросы