# #go
Вопрос:
Если я передаю значение int в структуре (в моем конкретном случае, аргументы rpc), язык не позволяет, чтобы атрибут был равен нулю. Пустое значение для int равно 0.
Но Go использует 0-индексированные массивы. Мне нужен способ отличить пустое значение от индекса 0. Существует ли идиоматическое решение этой проблемы?
// this is psuedo-code I had written before hitting this problem
if (args.maybeIndex != nil) {
doSomething(sliceOfNodes[args.maybeIndex])
}
Ответ №1:
Если вы кодируете свои int по значению, то вы мало что можете с этим поделать — значение по умолчанию равно 0.
Распространенным способом обеспечения возможности обнуления в кодировках в Go является использование типов указателей. Использование a *int
вместо an int
позволяет различать «нет» и 0.
Например, на примере JSON рассмотрим структуру:
type Options struct {
Id *string `json:"id,omitempty"`
Verbose *bool `json:"verbose,omitempty"`
Level *int `json:"level,omitempty"`
Power *int `json:"power,omitempty"`
}
И эти данные:
{
"id": "foobar",
"verbose": false,
"level": 10
}
Обратите внимание, что «мощность» не указана. Вы могли бы написать десериализатор:
func parseOptions(jsn []byte) Options {
var opts Options
if err := json.Unmarshal(jsonText, amp;opts); err != nil {
log.Fatal(err)
}
if opts.Power == nil {
var v int = 10
opts.Power = amp;v
}
return opts
}
Это устанавливает значение по умолчанию «мощность», если оно не указано. Это позволяет вам различать « power
не присутствовал» и « power
присутствовал, и его значение было 0″.
Если ваш механизм кодирования / RPC не допускает указателей, вы можете обойти это, создав другое логическое поле с именем «присутствует индекс» или что-то в этом роде.
Наконец, подумайте о разработке своей программы, чтобы сделать ее устойчивой к различиям между «не установлено» и «установлено значение по умолчанию». IOW, просто примите, что значения по умолчанию и неуказанные данные-это одно и то же. В долгосрочной перспективе это приведет к более чистому дизайну и коду и будет менее подвержено ошибкам.
Комментарии:
1. круто, спасибо за подробный ответ Илай. Очень полезно проверить эти подходы у кого-то с опытом. FWIW Я думаю, что ваш совет об устойчивости между двумя состояниями-лучший маршрут, так как моя проблема заключается только в первых нескольких вызовах, вероятно, моим решением будет какое-то состояние node.isReady.