web-dev-qa-db-ja.com

Scala:引数リストの一部としてタプルを解凍する

メソッド呼び出しのタプルの結果を、別のメソッドの引数リストのpartとして送信しようとしています。

ターゲットメソッド

_def printResult(title: String, result: Int, startTime: Long, endTime: Long)
_

メソッドからの戻り、部分引数リスト

_def sendAndReceive(send: Array[Byte]): (Int, Long, Long)
_

つまり、printResult(String, (Int, Long, Long))を呼び出そうとしています。メソッドの戻りシグネチャがメソッド呼び出しと一致する場合は、

_(printResult _).tupled(sendAndReceive(heartbeat))
_

これにより、構文エラーが発生します

_printresult("Hi", Function.tupled(sendAndReceive(heartbeat))
_

Workaround

タプルを手動で解凍し、メソッドを呼び出すときにそれを使用することに頼っています

_val Tuple = sendAndReceive(heartbeat)
printResult("Heartbeat only", Tuple._1, Tuple._2, Tuple._3)
_

引数リストの一部としてタプルを解凍して送信するためのよりエレガントな方法はありますか?

参考文献

Scala:関数の引数でタプルを分解する

パラメータリストとしてタプルを使用してメソッドを呼び出す

タプルの解凍はScalaのパラメーターリストで直接サポートされますか?

マップ操作でのタプルアンパック

14
Hanxue

次のことができます。

val (result, startTime, endTime) = sendAndReceive(heartbeat)
printResult("Heartbeat only", result, startTime, endTime)
17
Carl

この関数シグネチャに接続していますか?

def printResult(title: String, result: Int, startTime: Long, endTime: Long)

それがあなたのコードであり、それを変更できる場合は、代わりに次のようにカリー化を試して使用することができます。

def printResult(title: String)(result: Int, startTime: Long, endTime: Long)

次に、次のように実行できます。

printResult("Curried functions!") _ tupled(sendAndReceive(heartbeat))
4
kapunga

1つのアプローチには、たとえば次のようなタプルのケースクラスが含まれます。

case class Result(result: Int, startTime: Long, endTime: Long) {
  override def toString() = s"$result ($startTime to $endTime)"
}

def sendAndReceive(send: Array[Byte]): Result = {
  // body
  Result(1,2,3)
}

def printResult(title: String, res: Result) = println(title + res)
1
elm

これは、 shapeless を使用してタプルを解凍せずに(そして関数を2倍にすることなく)実際に達成できます。

_import shapeless.syntax.std.Tuple._

(printResult _).tupled("Hi" +: sendAndReceive(???))
_

"Hi" +: sendAndReceive(???)は、値_"Hi"_をsendAndReceiveによって返されるタプルの前に追加するだけです。

1