Логичным решением было бы использовать *string
, как упоминал Айнар-Г. Этот другой ответ подробно описывает возможности получения указателя на значение (int64
, но то же самое работает и для string
). Обертка - еще одно решение.
Используя только string
Необязательный string
означает string
плюс 1 конкретное значение (или состояние), говорящее «не строка» (а null
).
Это 1 конкретное значение может быть сохранено (сигнализировано) в другой переменной (например, bool
), и вы можете упаковать string
и bool
в struct
, и мы доберемся до оболочки, но это не вписывается в случай «использования только string
" (но все еще является жизнеспособным решением).
Если мы хотим придерживаться только string
, мы можем взять 1 конкретное значение из возможных значений типа string
(который имеет «бесконечность» возможных значений, поскольку длина не ограничена (или, может быть, это так, как должно быть int
). но это ничего)), и мы можем назвать это конкретное значение значением null
, значением, которое означает "не строка".
Наиболее удобным значением для указания null
является нулевое значение string
, то есть пустое string
: ""
. Назначение этого элемента null
имеет то удобство, что всякий раз, когда вы создаете переменную string
без явного указания начального значения, она будет инициализирована с ""
. Также при запросе элемента из map
, значение которого равно string
, также будет получено ""
, если ключ не находится в map
.
Это решение подходит для многих реальных случаев использования. Если необязательный string
должен быть именем человека, например, пустое string
на самом деле не означает действительное имя человека, поэтому вы не должны разрешать это в первую очередь.
Конечно, могут быть случаи, когда пустое string
действительно представляет допустимое значение переменной типа string
. Для этих вариантов использования мы можем выбрать другое значение.
В Go string
фактически представляет собой срез байтов, доступный только для чтения. См. сообщение в блоге Строки, байты, руны и символы в Go, где это подробно объясняется.
Таким образом, string
— это байтовый фрагмент, который представляет собой байты в кодировке UTF-8 в случае действительного текста. Предполагая, что вы хотите сохранить действительный текст в своем необязательном string
(если вы этого не сделаете, вы можете просто использовать вместо него []byte
, который может иметь значение nil
), вы можете выбрать значение string
, которое представляет недопустимую последовательность байтов UTF-8. и, таким образом, вам даже не придется идти на компромисс, чтобы исключить действительный текст из возможных значений. Самая короткая недопустимая последовательность байтов UTF-8 составляет всего 1 байт, например 0xff
(есть и другие). Примечание: вы можете использовать функцию utf8.ValidString()
, чтобы узнать, является ли значение string
допустимым текстом. (допустимая последовательность байтов в кодировке UTF-8).
Вы можете сделать это исключительное значение const
:
const Null = "\xff"
Такой короткий также означает, что будет очень быстро проверить, равно ли string
этому.
И по этому соглашению у вас уже есть необязательный string
, который также допускает пустое string
.
Попробуйте его на Go Playground.
const Null = "\xff"
func main() {
fmt.Println(utf8.ValidString(Null)) // false
s := Null
fmt.Println([]byte(s)) // [255]
fmt.Println(s == Null) // true
s = "notnull"
fmt.Println(s == Null) // false
}
person
icza
schedule
09.06.2015
*int64
, но вы можете использовать те же решения для*string
. - person icza   schedule 09.06.2015""
— это нулевое значение для строки в go. Это идиоматично, но, может быть, вам нужно это различие? - person SkyeC   schedule 09.06.2015