Как преобразовать интерфейс {} в строку?


114

Я использую docopt для анализа аргументов командной строки. Это работает, и в результате получается карта, например

map[<host>:www.google.de <port>:80 --help:false --version:false]

Теперь я хотел бы объединить hostи portзначение в строку с двоеточием между двумя значениями. В основном, что-то вроде:

host := arguments["<host>"] + ":" + arguments["<port>"]

К сожалению, это не работает, так как я получаю сообщение об ошибке:

недопустимая операция: arguments [""] + ":" (несовпадающие типы интерфейса {} и строки)

Поэтому, очевидно, мне нужно преобразовать значение, которое я получаю от карты (а это просто interface{}, так что это может быть что угодно) в строку. Теперь мой вопрос: как мне это сделать?


Ответы:


153

Вам нужно добавить утверждение типа .(string) . Это необходимо, потому что карта имеет тип map[string]interface{}:

host := arguments["<host>"].(string) + ":" + arguments["<port>"].(string)

Последняя версия Docopt возвращает объект Opts , у которого есть методы для преобразования:

host, err := arguments.String("<host>")
port, err := arguments.String("<port>")
host_port := host + ":" + port

7
Хотел бы добавить, что это называется Утверждение типа - golang.org/ref/spec#Type_assertions . Однажды мне было сложно понять эту точную терминологию.
Сриджит Рамакришнан 02

Если аргументы ["<host>"]
равны

89

Вам не нужно использовать утверждение типа, вместо этого просто используйте %vспецификатор формата с Sprintf:

hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])

Это было единственное, что я мог заставить работать для меня, когда пытался ввести приведенный интерфейс {} как строки.
FilBot3

1
Для меня это не сработало. Это закончилось тем, что вместо строки напечатали байтовые диаграммы ASCII, например, 201 стало "[50,48,49]", поэтому я закончил тем, что вместо этого использовал fmt.Sprintf ("% s", theThing) ...
Фелипе Вальдес

18

Чтобы расширить то, что сказал Питер: поскольку вы хотите перейти от интерфейса {} к строке, утверждение типа приведет к головной боли, поскольку вам нужно учитывать несколько входящих типов. Вам нужно будет подтвердить каждый возможный тип и убедиться, что он именно тот тип, прежде чем использовать его.

Использование fmt.Sprintf ( https://golang.org/pkg/fmt/#Sprintf ) автоматически обрабатывает преобразование интерфейса. Поскольку вы знаете, что желаемый тип вывода всегда является строкой, Sprintf обработает любой тип, стоящий за интерфейсом, без кучи дополнительного кода от вашего имени.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.