2014-12-07 3 views
2

Рассмотрим следующий пример: http://play.golang.org/p/eAot_sVwNDКак избежать реализации методов интерфейса, которым нужен приемник указателя?

package main 

import "fmt" 

type Incrementor interface { 
    Increment() 
} 

type Counter struct { 
    i int 

    Incrementor 
} 

func (c *Counter) Increment(){ 
    c.i++ 
} 

func main() { 
    var c Incrementor 
    c = &Counter{} 
    c.Increment() 
    fmt.Println(c) 
} 

Unfortunatelly Мне нужно c = &Counter{} потому что Counter.Increment() реализация имеет указатель приемника иначе c.Increment() вызовы не сможет изменить c.x свойство:

func (c Counter) Increment(){ 
    c.i++ // no errors, but now we increment c.x having a copy of c as context 
} 

Как сделать оригинальные работы по внедрению без & на c = &Counter{}? Другими словами, как избежать необходимости в приемнике указателя на реализацию C.Increment?

Это просто нит, но я думаю, что, возможно, указатель не нужен, чтобы сделать это в Go.

ответ

2

Вы могли бы рассмотреть вопрос о определении NewCounter функцию, которая инкапсулирует инициализацию вашего типа (или какой-то 3 участника) и возвращает *Counter. Использование может выглядеть примерно так:

func main() { 
    c := NewCounter() 
    c.Increment() 
    fmt.Println(c) 
} 
+0

Ницца, мы видим этот шаблон повсюду внутри go std libs. – marcio

4

Это просто нит, но я думаю, что, возможно, указатель не нужен, чтобы сделать это в Go.

Учитывая, что Go использует, чтобы передать все по значение, указатель приемника является естественным способом добиться того, что вы хотите.
Это подтверждается Go FAQ:

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

Вы бы найти подобный вывод в «Things I Wish Someone Had Told Me About Golang: pointers»

+0

Итак, нет способа избавиться от инициализации & '& Counter {}'? – marcio

+1

Мотив для этой проблемы заключается в том, что мне очень неприятно инициализировать структуры по ссылке при использовании пакетов партии tirhd, поэтому я стараюсь избегать их как можно больше. Вы не знаете, как инициализировать вещи, пока не увидите ошибку компиляции. – marcio

+1

@marcioAlmada Я понимаю, но я не знаю, как естественным образом избежать интуиции указателя в Go, когда у вас есть метод, который изменяет его содержимое. – VonC

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