これは具体的な方法ではないので、他の回答者とは異なり、より一般的な方法を使用します。
可変引数について ( ...
)
...
ここでは、「省略記号」と呼ばれ、関数が可変数の引数を受け取ることができることを示します。これは、varargs (または var-args、または他のスペル) と呼ばれることがよくあります。これは可変個引数関数と呼ばれます。
次の署名によると、それは単に次のことを意味します。
func Printf(format string, v ...interface{}) (n int, err error) {}
Printf
type の最初の引数が必要string
で、次に type の 0 から N 個の引数が必要ですinterface{}
。そのタイプについては、次のセクションで詳しく説明します。
任意の数の引数を指定できる機能は非常に便利に思えますが、トピックから外れるリスクがあるため、ここではあまり詳細には触れませんが、言語の実装によってはいくつかの注意事項があります。
- メモリ消費量の増加、
- 読みやすさの低下、
- コードのセキュリティが低下します。
上記のリソースから理由を調べるのはあなたに任せます。
空のインターフェイス ( interface{}
)
この構文ビットはもう少し Go 固有ですが、ヒントは名前にあります: interface
.
インターフェイス (または Go のパラダイムに近いプロトコル) は、他のオブジェクトが準拠するための契約を定義する型です。コンピューティングのインターフェイスに関するこのウィキペディアの記事によると(太字は強調、斜体は修正):
オブジェクト指向言語では、**「インターフェース」という用語は、データを含まないが、メソッドとして定義された動作を公開する抽象型を定義するためによく使用されます。そのインターフェースに対応するすべてのメソッドを持つクラスは、そのインターフェースを実装すると言われています。さらに、クラスは[一部の言語では])複数のインターフェイスを実装できるため、同時に異なる型になる可能性があります。
したがって、インターフェースは型定義です。(関数またはメソッド呼び出しで)オブジェクトを交換できる場所ならどこでも、交換するオブジェクトの型を、特定の class ではなく、インターフェイスの観点から定義できます。これにより、後のコードで異なるオブジェクト タイプを交換する同じ関数を使用できます。_[なりたい]_ 一般的で再利用可能。
Go の Empty Interface に戻ります。
Go は強く型付けされた言語であり、現在の (1.1) 言語仕様では gollows として記述されているInterface Typesを含むいくつかの組み込み型があります。
インターフェイス タイプは、そのインターフェイスと呼ばれるメソッド セットを指定します。インターフェイス型の変数は、インターフェイスの任意のスーパーセットであるメソッド セットを持つ任意の型の値を格納できます。このようなタイプは、インターフェースを実装すると言われています。
Printf
さらに下に、の署名に見られる構造を紹介しますinterface{}
(私の太字は強調):
型は、そのメソッドの任意のサブセットを含む任意のインターフェイスを実装するため、いくつかの異なるインターフェイスを実装できます。たとえば、すべての型は空のインターフェイスを実装します。
interface{}
これは基本的に、任意の型を「空のインターフェイス」として表すことがPrintf
できるため、これらの varargs に対して任意の型の変数を受け入れることができることを意味します。
他の言語との簡単な比較
歴史的に、名前printf
は C 関数と同じ名前のバイナリに由来し、printf
「フォーマットされた印刷」を意味しますが、初期の言語には可変個引数の出力関数があり、可変個引数関数は他の多くのシナリオで使用されます。ただし、printf
そのような用途の代表的な例と見なされることがよくあります。Cでの署名は次のとおりです。
int printf(const char *format, ...);
その実用性の結果として、varargs とprintf
のおなじみの顔がほとんどの言語に現れます...
Java ではprintf
、特にPrintStream
クラスから、複数の形式で存在します。
public PrintStream printf(String format, Object... args)
他の言語の中には、変数引数の指定を気にせず、それを暗黙的にするものがあります。たとえば、JavaScript では、arguments
関数内の特別な変数により、プロトタイプと一致するかどうかに関係なく、関数に渡される任意の引数にアクセスできます。
メソッドはconsole.log()
に似た例になりますがprintf
、次の疑似署名はわかりやすくするために展開されています (ただし、実際には単純に を使用していますarguments
)。
console.log(obj1 [, obj2, ..., objN);
console.log(msg [, subst1, ..., substN);