2016-04-13 2 views
0

Я иду от фона Node.js, и типичный образец должен иметь функцию, которая принимает объект опции из, то есть объект, где вы устанавливаете свойства для дополнительных параметров, таких как:Как предоставить дополнительные параметры в Go?

foo({ 
    bar: 23, 
    baz: 42 
}); 

Это «эквивалент» JavaScript для необязательных и именованных параметров.

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

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

Так что я в конечном итоге с:

  • вызова функции, которая создает структура и затем заполняет его значениями по умолчанию.
  • Замените значения, которые я хотел бы изменить.
  • Вызовите функцию, которую я действительно хочу вызвать и передать структуру.

Это довольно сложный и длительный по сравнению с решением JavaScript.

Действительно ли это идиоматический способ иметь дело с необязательными и именованными параметрами в Go, или есть более простая версия?

+0

Возможно, вам будет проще показать путь 'Go', если вы представили пример, демонстрирующий проблему, с которой вы сталкиваетесь. – sberry

+0

http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis Дает большое представление об этой теме –

ответ

1

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

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

Объект опций - довольно распространенная идиома. В файле etcd client library есть несколько примеров (SetOptions, GetOptions, DeleteOptions), аналогичные приведенным ниже.

type MyOptions struct { 
    Field1 int 
    Field2 string 
} 

func DoAction(arg1, arg2 string, options *MyOptions){ 
    var defaultValue1 int = 30  // some reasonable default 
    var defaultValue2 string = "west" // some reasonable default 

    if MyOptions != nil { 
     defaultValue1 = options.Field1 // override with our values 
     defaultValue2 = options.Field2 
    } 
    doStuffWithValues 
0

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

Если все варианты одного типа используют map[string]type. Это дает вам именованные параметры и как можно меньше или меньше.

Их существование легко проверить с чем-то вроде

if val, exists := opts["bar"]; exists { 
    // Do something here 
} 

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

Если параметры не одного типа, вы можете использовать map[string]interface{}, что позволит хранить любые типы на карте. Вам просто нужно будет отображать значения после извлечения.

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