Goのバリアント関数

ClockbirdsによるフェードMail.ruCloud Solutions



チームは、Goのさまざまな機能に関する記事翻訳しました。その作者は、バリアディック関数が通常の関数とどのように異なるか、そしてそれらを作成する方法を説明しています。



バリアディック機能とは



関数は、特定のタスクを実行するために設計されたコードの一部です。関数には1つ以上の引数が渡され、1つ以上の結果が返されます。



バリアント関数は通常の関数と同じですが、無限または可変の数の引数を取ることができます。



func f(elem ...Type)


これは、典型的なバリアディック関数の構文がどのように見えるかです。...ボクシング演算子とも呼ばれる演算子は、すべての型引数Typeをパラメータに格納するようにGoに指示しますelem言い換えると、Goはelem、タイプ[]Type、つまりスライスを持つ変数作成します。そして、関数に渡されたすべての引数はスライスに格納されますelem



関数の例を見てみましょうappend()



append([]Type, args, arg2, argsN)


この関数appendは、最初の引数がタイプのスライスでありType、その後に任意の数の引数が続くことを想定しています。しかし、どのようにしてスライスs2スライス追加しますs1か?



関数の定義から、append()2つのスライスを渡すことはできませんType型引数は1つだけです。したがって、unboxing演算子...を使用して、スライスを一連の引数に解凍します。次に、それらを関数に渡すことができますappend



append(s1, s2...)


...パッキング演算子とアンパッキング演算子の両方を示します。ボックス化解除演算子は、常に変数名の後に表示されます。



この例では、スライスs1s2同じタイプです。私たちは通常、関数のパラメーターとそれが取る引数の数を知っています。関数は、accept渡されたパラメーターの数をどのように知るのですか?



関数宣言appendを見ると、式がわかりますelems ...Type。 2番目から始まるすべての引数をスライスにパックしますelems



func append(slice []Type, elems ...Type) []Type


関数宣言の最後の引数のみを変数にすることができます。



したがって、関数の最初の引数appendはスライスとして定義されているため、スライスのみです。後続のすべての引数は、という名前の単一の引数にパックされelemsます。



それでは、独自のバリアディック関数を作成する方法を見てみましょう。



バリアディック関数の作成方法



前述のように、バリアディック関数は、可変数の引数をとる通常の関数です。これを行うには、ボクシング演算子を使用する必要があります...Type最初の引数(乗算係数)と可変数の追加の型引数を



持つ関数getMultiples書いてみましょうそれらはスライスにパックされます空のスライス作成するために使用します。これはスライスと同じサイズです。ループを使用して、スライス要素。を掛けます結果を新しい空のスライス入れます。これは関数の結果として返されます。factorintintargs



makeargsfor rangeargsfactormultiples



func getMultiples(factor int, args ...int) []int {
	multiples := make([]int, len(args))
	for index, val := range args {
		multiples[index] = val * factor
	}
	return multiples
}


これは非常に単純な関数であり、ブロック内に適用しますmain()



func main() {
	s := []int{10, 20, 30}
	mult1 := getMultiples(2, s...)
	mult2 := getMultiples(3, 1, 2, 3, 4)
	fmt.Println(mult1)
	fmt.Println(mult2)
}




https://play.go.org/p/BgU6H9orhrn



上記の例で、スライスをgetMultiples2番目の引数として関数に渡すとどうなりますか?コンパイラはエラーを報告します引数の型としてgetMultiples使用することはできませんこれは、スライスにからのパラメータ期待するタイプがあるためです。s (type [] int)int[]int, getMultiplesint



スライスがvariadic関数に渡される方法



スライスは配列への参照です。では、ボックス解除演算子を使用してスライスをvariadic関数に渡すとどうなりますか? Goは新しいスライスを作成しargsますsか、それとも古いスライスを使用しますか?



比較ツールがないためargs == s、スライスを変更する必要がありますargs。次に、元のスライスが変更されているかどうかを確認しますs





https://play.go.org/p/fbNgVGu6JZO



上記の例では、関数を少し変更しましたgetMultiples。そして、新しいスライスを作成する代わりに、計算結果をスライスの要素に割り当てargs、入力要素を乗算された要素に置き換えます。



その結果、元のスライスの値がわかりますs変更されました。unboxing演算子を介してvariadic関数に引数を渡すと、Goは元のデータ配列への参照を使用して新しいスライスを作成します。間違えないように注意してください。間違えると、計算の結果、元のデータが変更されます。



幸運を!



他に読むべきこと:



  1. GoおよびCPUキャッシュ
  2. バックエンド開発者がGoプログラミング言語を学ぶ必要がある理由
  3. デジタル変換に関するテレグラムチャネル



All Articles