Can Go имеют необязательные параметры? Или я могу просто определить две функции с тем же именем и другим числом аргументов?
Дополнительные параметры?
Ответ 1
Go не имеет необязательных параметров и не поддерживает перегрузку метода:
Отправка метода упрощается, если он не нужно выполнять сопоставление типов, как Что ж. Опыт работы на других языках сказал, что с методы с тем же именем, но иногда были разные подписи полезно, но также может быть путают и хрупки на практике. Соответствие только по названию и требование согласованность в типах была крупной упрощение решения в стиле Go система.
Ответ 2
Вы можете использовать структуру, которая включает в себя параметры:
type Params struct {
  a, b, c int
}
func doIt(p Params) int {
  return p.a + p.b + p.c 
}
// you can call it without specifying all parameters
doIt(Params{a: 1, c: 9})
Ответ 3
Хорошим способом достижения чего-то вроде необязательных параметров является использование переменных переменных. Функция фактически получает срез любого типа, который вы указываете.
func foo(params ...int) {
    fmt.Println(len(params))
}
func main() {
    foo()
    foo(1)
    foo(1,2,3)
}
Ответ 4
Для произвольного, потенциально большого количества необязательных параметров, хорошая идиома заключается в использовании Функциональных опций.
Для вашего типа Foobar сначала напишите только один конструктор:
func NewFoobar(options ...func(*Foobar) error) (*Foobar, error){
  fb := &Foobar{}
  // ... (write initializations with default values)...
  for _, op := range options{
    err := op(fb)
    if err != nil {
      return nil, err
    }
  }
  return fb, nil
}
где каждый параметр является функцией, которая мутирует Foobar. Затем предоставите удобные способы для использования пользователем или создания стандартных параметров, например:
func OptionReadonlyFlag(fb *Foobar) error {
  fb.mutable = false
  return nil
}
func OptionTemperature(t Celsius) func(*Foobar) error {
  return func(fb *Foobar) error {
    fb.temperature = t
    return nil
  }
}
Для краткости вы можете указать имя типа параметров (Игровая площадка):
type OptionFoobar func(*Foobar) error
Если вам нужны обязательные параметры, добавьте их в качестве первых аргументов конструктора перед переменным options.
Основными преимуществами идиомы функциональных опций являются:
- ваш API может расти со временем, не нарушая существующий код, потому что подпись constuctor остается прежней, когда нужны новые параметры.
- он позволяет использовать прецедент по умолчанию как самый простой: никаких аргументов вообще!
- он обеспечивает точное управление инициализацией сложных значений.
Эта техника была придумана Rob Pike, а также продемонстрирована Дейв Чейни.
Ответ 5
В Go не поддерживаются ни дополнительные параметры, ни перегрузка функций. Go поддерживает переменное количество параметров: Передача аргументов в... параметры
Ответ 6
Нет - нет. На Перейти для программистов на С++,
Go не поддерживает функцию перегрузка и не поддерживает пользователя определенных операторов.
Я не могу найти одинаково ясное утверждение о том, что необязательные параметры не поддерживаются, но они также не поддерживаются.
Ответ 7
Вы можете инкапсулировать это довольно хорошо в func, подобном тому, что ниже.
package main
import (
        "bufio"
        "fmt"
        "os"
)
func main() {
        fmt.Println(prompt())
}
func prompt(params ...string) string {
        prompt := ": "
        if len(params) > 0 {
                prompt = params[0]
        }
        reader := bufio.NewReader(os.Stdin)
        fmt.Print(prompt)
        text, _ := reader.ReadString('\n')
        return text
}
В этом примере запрос по умолчанию имеет двоеточие и пробел перед ним.,.
: 
., однако вы можете переопределить это, предоставив параметр функции приглашения.
prompt("Input here -> ")
Это приведет к следующему приглашению.
Input here ->
Ответ 8
В итоге я использовал комбинацию структуры params и variadic args. Таким образом, мне не пришлось менять существующий интерфейс, который был использован несколькими службами, и моя служба смогла передать дополнительные параметры по мере необходимости. Пример кода на игровой площадке golang: https://play.golang.org/p/G668FA97Nu
Ответ 9
Я немного опаздываю, но если вам нравится свободный интерфейс, вы можете создать свои сеттеры для таких цепочек:
type myType struct {
  s string
  a, b int
}
func New(s string, err *error) *myType {
  if s == "" {
    *err = errors.New(
      "Mandatory argument `s` must not be empty!")
  }
  return &myType{s: s}
}
func (this *myType) setA (a int, err *error) *myType {
  if *err == nil {
    if a == 42 {
      *err = errors.New("42 is not the answer!")
    } else {
      this.a = a
    }
  }
  return this
}
func (this *myType) setB (b int, _ *error) *myType {
  this.b = b
  return this
}
И затем назовите его следующим образом:
func main() {
  var err error = nil
  instance :=
    New("hello", &err).
    setA(1, &err).
    setB(2, &err)
  if err != nil {
    fmt.Println("Failed: ", err)
  } else {
    fmt.Println(instance)
  }
}
Это похоже на Идиомы функциональных опций, представленные в ответе @Ripounet, и пользуется теми же преимуществами, но имеет некоторые недостатки:
- Если произошла ошибка, она не будет отменена немедленно, поэтому она будет немного менее эффективной, если вы ожидаете, что ваш конструктор будет часто сообщать об ошибках.
-  Вам придется потратить строку, объявляющую переменную errи обнуляющую ее.
Существует, однако, небольшое преимущество, этот тип вызовов функций должен быть проще для встроенного компилятора, но я действительно не специалист.
