インターフェースを文字列に変換する方法は?


114

コマンドライン引数を解析するためにdocoptを使用しています。これは機能し、次のようなマップになります

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

次に、hostport値を連結して、2つの値の間にコロンを付けた文字列にします。基本的に、次のようなもの:

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 2015

arguments ["<host>"]がnilの場合、パニックになります
Savash

89

タイプアサーションを使用する必要はなく、代わりに%vフォーマット指定子を使用しますSprintf

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

これは、キャストインターフェイス{}を文字列として入力しようとしたときに機能する唯一の方法でした。
FilBot3 2017年

1
私にとって、これはうまくいきませんでした。これは、201が "[50,48,49]"になるような文字列の代わりにバイトASCIIチャートを印刷することになったので、代わりにfmt.Sprintf( "%s"、theThing)を使用することになりました...
Felipe Valdes

18

Peterの発言をさらに詳しく説明します。インターフェイス{}から文字列に移行しようとしているため、複数の入力タイプを考慮する必要があるため、タイプアサーションは頭痛の種につながります。使用する前に、可能な各タイプをアサートし、そのタイプであることを確認する必要があります。

fmt.Sprintf(https://golang.org/pkg/fmt/#Sprintf)を使用すると、インターフェース変換が自動的に処理されます。目的の出力タイプが常に文字列であることを知っているので、Sprintfは、ユーザーに代わって余分なコードを束ねることなく、インターフェースの背後にあるすべてのタイプを処理します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.