如何改造Scala隐式类中的pimp方法以接收元组?
tupled (and How to Fix It) The issue here boils down to how Scala handles implicit conversions and method-to-function lifting. When you use (""".f _, the compiler can't automatically apply the implicit Pimps conversion because it's not in a context where a function type is explicitly expected. Normally, when you call (""".f(1,1), the compiler wraps the string in Pimps("") automatically, but unapplied methods (like f _) don't trigger this conversion unless the compiler knows it needs a function.
Here are several clean ways to fix this:
Solution 1: Add a Tuple-Accepting Overload to Your Implicit Class
The simplest fix is to add an overload of f that directly takes a tuple. This lets you call the method with a tuple without needing tupled:
val t = (0f, 0f) implicit class Pimps[A <: Object](a: A) { def f(x: Float, y: Float): A = { println(s"f($x, $y)"); a } // Add this overload to accept a tuple def f(tuple: (Float, Float)): A = f(tuple._1, tuple._2) } // Now this works! """.f(t)
Solution 2: Explicitly Trigger the Implicit Conversion First
You can manually create the Pimps instance for your string, then lift the method to a function and call tupled:
val t = (0f, 0f) implicit class Pimps[A <: Object](a: A) { def f(x: Float, y: Float): A = { println(s"f($x, $y)"); a } } // Create the Pimps instance explicitly val pimpedString = Pimps("") // Now lift the method to a function and use tupled (pimpedString.f _).tupled(t)
Solution 3: Explicitly Specify the Function Type
By telling the compiler you want a Function2[Float, Float, String], it will automatically apply the implicit conversion to get the Pimps instance, then lift the method to the desired function:
val t = (0f, 0f) implicit class Pimps[A <: Object](a: A) { def f(x: Float, y: Float): A = { println(s"f($x, $y)"); a } } // Explicitly define the function type val fFunc: (Float, Float) => String = (""".f _) // Now tupled works as expected fFunc.tupled(t)
Solution 4: Use Function.tupled with an Explicit Type Annotation
You can also use Function.tupled directly, but you need to help the compiler resolve the function type:
val t = (0f, 0f) implicit class Pimps[A <: Object](a: A) { def f(x: Float, y: Float): A = { println(s"f($x, $y)"); a } } // Use Function.tupled with an explicit type to trigger the conversion Function.tupled[Float, Float, String]((""".f _))(t)
Each of these solutions works, but Solution 1 is the most idiomatic and concise for everyday use—it lets you call the method with either individual arguments or a tuple without extra boilerplate.
内容的提问来源于stack exchange,提问作者menfon

