2016-05-10 6 views
41

структурах Есть несколько ответов/методы к ниже вопросу:Как установить значения по умолчанию в golang

  1. Как установить значения по умолчанию для golang структур?
  2. Как инициализировать в golang структур

У меня есть несколько ответов, но требует дальнейшего обсуждения.

+1

Связанный: [? Как убедиться в том, что метод используется после того, как объект создан в golang] (http://stackoverflow.com/questions/36826232/how-to-make-sure-that- a-method-is-used-after-an-object-is-created-in-golang) – icza

+0

@icza Вы отвечаете, даете предоставить способ сделать это, но, пройдя по заголовку вопроса, он никоим образом не похож или не доступен для поиска так как это очень конкретный вопрос. Однако я добавлю ссылку в свой ответ. – Prateek

+0

Здесь два вопроса, выберите один.Предполагая, что вы выбираете первый вопрос (в соответствии с заголовком вопроса), будьте более конкретным относительно ваших предыдущих исследований и где ваши другие ответы требуют больше обсуждений. –

ответ

15
  1. Принудительного метод, чтобы получить (-структуру конструктора путь).

Хороший дизайн, чтобы сделать ваш тип неэкспортируемыми, но обеспечивают экспортированной конструктор функции, как NewMyType(), в котором вы можете правильно инициализации структуры/типа. Также верните тип интерфейса, а не конкретный тип , и интерфейс должен содержать все, что нужно , чтобы сделать с вашим значением. Конечно, ваш конкретный тип должен реализовывать интерфейс .

Это можно сделать, просто сделав сам тип невозвращенным. Вы можете экспортировать функцию NewSomething и даже поля Text и DefaultText, но просто не экспортируете тип структуры что-то

  1. Другой способ настроить его для собственного модуля - использовать Config struct to set default values (Вариант 5 в ссылке) Не очень хороший способ.
+2

Это теперь неработающая ссылка (404) : http://joneisen.tumblr.com/post/53695478114/golang-and-default-values ​​ –

+2

Он доступен на [wayback machine] (https://web.archive.org/web/20160818125551/https joneisen.tumblr.com/post/53695478114/golang-and-default-values). – n8henrie

+0

'golint' будет жаловаться на экспорт функции, которая возвращает неактивный тип:' exported func NewPrivate возвращает неактивный тип mypkg.private, который может раздражать, чтобы использовать ' – m90

33

Возможной Идея заключается в том, чтобы написать отдельную функцию конструктора

//Something is the structure we work with 
type Something struct { 
    Text string 
    DefaultText string 
} 
// NewSomething create new instance of Something 
func NewSomething(text string) Something { 
    something := Something{} 
    something.Text = text 
    something.DefalultText = "default text" 
    return something 
} 
+0

Да, это один из способов, о котором я упомянул в своем ответе, но мы никоим образом не можем заставить кого-либо использовать эту функцию. – Prateek

+0

@Prateek это либо это, либо использовать интерфейс, который был бы уродливым и сложным. – OneOfOne

+8

@Prateek да, вы можете заставить людей использовать этот конструктор, если вы просто сделаете сам тип невозвращенным. Вы можете экспортировать функцию 'NewSomething' и даже поля' Text' и 'DefaultText', но просто не экспортируйте struct type' something'. –

3

Одна из проблем, с вариантом 1 в ответ от Виктора Zamanian в том, что если тип не экспортируется, то пользователи пакета не может объявить его в качестве типа параметров функции и т.д. Один из способов обойти это будет для экспорта интерфейса вместо структуры, например

package candidate 
// Exporting interface instead of struct 
type Candidate interface {} 
// Struct is not exported 
type candidate struct { 
    Name string 
    Votes unit32 // Defaults to 0 
} 
// We are forced to call the constructor to get an instance of candidate 
func New(name string) Candidate { 
    return candidate{name, 0} // enforce the default value here 
} 

Что позволяет нам объявлять типы параметров функции с использованием экспортированного интерфейса кандидата. Единственным недостатком, который я вижу из этого решения, является то, что все наши методы должны быть объявлены в определении интерфейса, но вы можете утверждать, что это хорошая практика в любом случае.

0

От https://golang.org/doc/effective_go.html#composite_literals:

Иногда нулевое значение не является достаточно хорошим и инициализации конструктора необходимо, так как в этом примере, полученного из пакета зева.

func NewFile(fd int, name string) *File { 
    if fd < 0 { 
     return nil 
    } 
    f := new(File) 
    f.fd = fd 
    f.name = name 
    f.dirinfo = nil 
    f.nepipe = 0 
    return f 
} 
Смежные вопросы