3

次の例を検討してください

def foo(a: Int, b: Int = 100) = a + b
def bar(a: Int, b: Int = 100) = foo(a, b) * 2

これは機能しますが、両方の関数でbに同じデフォルト値を指定する必要があることに注意してください。私の意図は実際には次のとおりです

def bar(a: Int, b: Int) = foo(a, b) * 2
def bar(a: Int)    = foo(a) * 2

ただし、オプションの引数が多く、チェーンに追加の関数(同じ方法でbarを呼び出すbazなど)がある場合、これは面倒になります。これをscalaで表現するためのより簡潔な方法はありますか?

4

2 に答える 2

4

あるとは思いません。二重化関数を使用してfooを作成する場合:

val bar = (foo _).curried((_: Int)) andThen ((_: Int) *2)
// (please, please let there be a simpler way to do this...)

関数オブジェクトにはデフォルトの引数がないため、デフォルトの引数は失われます。

ユースケースでそれだけの価値がある場合は、複数の個別の引数の代わりに渡す引数を含むケースクラスを作成できます。

case class Args(a: Int, b: Int = 100, c: Int = 42, d: Int = 69)
def foo(args: Args) = { import args._; a + b + c + d }
def bar(args: Args) = foo(args) * 2
于 2012-08-09T04:02:00.753 に答える
2

を使用することをお勧めしますOption

def bar(a: Int, b: Option[Int] = None) = b match {
  case Some(x) => foo(a,x) * 2
  case _ => foo(a) * 2
}

これはまさにあなたが望むことをするでしょう。別の方法は、varargsを使用することです。

def baz(a: Int)(b: Int*) = b.headOption match {
  case Some(x) => foo(a,x) * 2
  case _ => foo(a) * 2
}

パラメータがオプションであることは明らかなので、最初の方法をお勧めします。2番目の解決策は、のラッピングを処理するOptionことではありませんでしたが、コレクションの最初の要素のみが考慮されることは、署名では明確ではありません。baz(1)(2) == baz(1)(2,3,4,5)本当です。

編集

Option目的の呼び出しのように見えるものを作成するには、暗黙を使用できます。

implicit def int2Some(i: Int) = Some(i)

これで、関数を次のように呼び出すことができます。

bar(1,2)
bar(1,Some(2))
bar(1)
bar(1,None)

は、implicit便利な場所で自動的に呼び出されます。しかし、ユーザーが混乱する可能性があります。なぜ関数をのInt代わりに呼び出すことができるのでしょうかOption[Int]

于 2012-08-09T06:07:01.857 に答える