Як перетворити інтерфейс {} в рядок?


114

Я використовую docopt для аналізу аргументів командного рядка. Це працює, і в результаті виходить карта, наприклад

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

Тепер я хотів би об'єднати значення hostта portзначення у рядок із двокрапкою між двома значеннями. В основному, щось таке:

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

На жаль, це не працює, оскільки я отримую повідомлення про помилку:

недійсна операція: аргументи [""] + ":" (інтерфейс невідповідних типів {} та рядок)

Тому очевидно, що мені потрібно перетворити значення, яке я отримую з карти (що справедливе 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 . У мене колись виникли проблеми з з'ясуванням цієї точної термінології.
Sreejith Ramakrishnan

Це спричинить паніку, якщо аргументи ["<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.