Jak przekonwertować interfejs {} na ciąg?

114

Używam docopt do analizowania argumentów wiersza polecenia. To działa i powoduje powstanie mapy, takiej jak

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

Teraz chciałbym, aby złączyć hosta portwartość ciągu z dwukropkiem w między tymi dwiema wartościami. Zasadniczo coś takiego jak:

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

Niestety to nie działa, ponieważ pojawia się komunikat o błędzie:

nieprawidłowa operacja: argumenty [""] + ":" (interfejs niezgodnych typów {} i ciąg znaków)

Więc oczywiście muszę przekonwertować wartość, którą otrzymuję z mapy (która jest po prostu interface{}, więc może to być cokolwiek) na ciąg. Teraz moje pytanie brzmi, jak mam to zrobić?

Golo Roden
źródło

Odpowiedzi:

153

Musisz dodać potwierdzenie typu .(string) . Jest to konieczne, ponieważ mapa jest typu map[string]interface{}:

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

Najnowsza wersja Docopt zwraca obiekt Opts, który ma metody konwersji:

host, err := arguments.String("<host>")
port, err := arguments.String("<port>")
host_port := host + ":" + port
Grzegorz Żur
źródło
7
Chciałbym dodać, że nazywa się to Asercją typu - golang.org/ref/spec#Type_assertions . Kiedyś miałem problem ze zrozumieniem tej dokładnej terminologii.
Sreejith Ramakrishnan
Spowoduje to panikę, jeśli argumenty ["<host>"] są zerowe
Savash
89

Nie musisz używać potwierdzenia typu, zamiast tego użyj specyfikatora %vformatu z Sprintf:

hostAndPort := fmt.Sprintf("%v:%v", arguments["<host>"], arguments["<port>"])
Peter Stace
źródło
To była jedyna rzecz, jaką mogłem wykonać, próbując wpisać interfejs rzutowania {} jako łańcuchy.
FilBot3
1
Dla mnie to nie zadziałało. Skończyło się na wydrukowaniu bajtowych wykresów ASCII zamiast ciągu, na przykład 201 stało się "[50,48,49]", więc zamiast tego użyłem fmt.Sprintf ("% s", theThing) ...
Felipe Valdes
18

Aby rozwinąć to, co powiedział Peter: Ponieważ chcesz przejść od interfejsu {} do ciągu znaków, asercja typu doprowadzi do bólu głowy, ponieważ musisz uwzględnić wiele typów przychodzących. Będziesz musiał potwierdzić każdy możliwy typ i sprawdzić, czy jest to ten typ, zanim go użyjesz.

Korzystanie z fmt.Sprintf ( https://golang.org/pkg/fmt/#Sprintf ) automatycznie obsługuje konwersję interfejsu. Ponieważ wiesz, że pożądanym typem wyjściowym jest zawsze ciąg, Sprintf obsłuży każdy typ za interfejsem bez dodatkowego kodu w Twoim imieniu.

justitan
źródło