Saya tahu pertanyaan ini sering muncul dengan cara yang berbeda. Tapi masih belum jelas bagi saya. Apakah ada cara untuk mencapai hal berikut.
def foo(a:Int, b:Int) = {}
foo(a,b) //right way to invoke foo
foo(getParams) // is there a way to get this working without explicitly unpacking the tuple??
def getParams = {
//Some calculations
(a,b) //where a & b are Int
}
scala
parameters
tuples
pramuka
sumber
sumber
Jawaban:
Ini adalah prosedur dua langkah. Pertama-tama ubah foo menjadi fungsi, lalu panggil tuple di atasnya untuk menjadikannya fungsi tupel.
sumber
@ dave-griffith sudah mati.
Anda juga dapat menghubungi:
Function.tupled(foo _)
Jika Anda ingin menjelajahi wilayah "jauh lebih banyak informasi daripada yang saya minta", ada juga metode yang dibangun ke dalam fungsi yang diterapkan sebagian (dan
Function
seterusnya) untuk kari. Beberapa contoh masukan / keluaran:scala> def foo(x: Int, y: Double) = x * y foo: (x: Int,y: Double)Double scala> foo _ res0: (Int, Double) => Double = <function2> scala> foo _ tupled res1: ((Int, Double)) => Double = <function1> scala> foo _ curried res2: (Int) => (Double) => Double = <function1> scala> Function.tupled(foo _) res3: ((Int, Double)) => Double = <function1> // Function.curried is deprecated scala> Function.curried(foo _) warning: there were deprecation warnings; re-run with -deprecation for details res6: (Int) => (Double) => Double = <function1>
Di mana versi curried dipanggil dengan beberapa daftar argumen:
scala> val c = foo _ curried c: (Int) => (Double) => Double = <function1> scala> c(5) res13: (Double) => Double = <function1> scala> c(5)(10) res14: Double = 50.0
Terakhir, Anda juga dapat membatalkan / melepas jika perlu.
Function
memiliki bawaan untuk ini:scala> val f = foo _ tupled f: ((Int, Double)) => Double = <function1> scala> val c = foo _ curried c: (Int) => (Double) => Double = <function1> scala> Function.uncurried(c) res9: (Int, Double) => Double = <function2> scala> Function.untupled(f) res12: (Int, Double) => Double = <function2>
sumber
Function.tupled(foo _)(getParams)
atau yang disarankan oleh Dave.EDIT:
Untuk menanggapi komentar Anda:
Dalam hal ini, trik ini tidak akan berhasil.
Anda dapat menulis metode pabrik di objek pendamping kelas Anda dan kemudian mendapatkan versi tuple dari
apply
metode tersebut menggunakan salah satu teknik yang disebutkan di atas.scala> class Person(firstName: String, lastName: String) { | override def toString = firstName + " " + lastName | } defined class Person scala> object Person { | def apply(firstName: String, lastName: String) = new Person(firstName, lastName) | } defined module Person scala> (Person.apply _).tupled(("Rahul", "G")) res17: Person = Rahul G
Dengan
case class
es Anda mendapatkan objek pendamping denganapply
metode gratis, dan dengan demikian teknik ini lebih nyaman digunakan dengancase class
es.scala> case class Person(firstName: String, lastName: String) defined class Person scala> Person.tupled(("Rahul", "G")) res18: Person = Person(Rahul,G)
Saya tahu itu banyak duplikasi kode tetapi sayangnya ... kami belum memiliki makro (belum)! ;)
sumber
Person.tupled(("Rahul", "G"))
berguna untuk melakukan ini pada objek pendamping yang ditulis tangan juga.Saya menghargai beberapa jawaban lain yang lebih dekat dengan apa yang Anda minta, tetapi saya merasa lebih mudah untuk proyek saat ini untuk menambahkan fungsi lain yang mengubah parameter tupel menjadi parameter terpisah:
def originalFunc(a: A, b: B): C = ... def wrapperFunc(ab: (A, B)): C = (originalFunc _).tupled(ab)
sumber
Sekarang, Anda dapat mengimplementasikan foo dan membuatnya mengambil parameter kelas Tuple2 seperti itu.
def foo(t: Tuple2[Int, Int]) = { println("Hello " + t._1 + t._2) "Makes no sense but ok!" } def getParams = { //Some calculations val a = 1; val b = 2; (a, b) //where a & b are Int } // So you can do this! foo(getParams) // With that said, you can also do this! foo(1, 3)
sumber