Вы можете определить неявное преобразование:
implicit def value2tuple[T](x: T): Tuple1[T] = Tuple1(x)
Неявное преобразование будет применяться, только если статический тип аргумента еще не соответствует типу параметра метода.Предполагая, что ваш метод принимает Product
аргумент
def m(v: Product) = // ...
, преобразование будет применяться к значению, не являющемуся продуктом, но не применяется к Tuple2
,например.Предупреждение: все классы дел расширяют черту Product
, поэтому преобразование также не будет применяться к ним .Вместо этого элементы product будут параметрами конструктора класса case.
Product
является наименьшей верхней границей классов TupleX
, но вы можете использовать класс типов, если хотите применить неявное преобразование Tuple1 ко всем не кортежам:
// given a Tupleable[T], you can call apply to convert T to a Product
sealed abstract class Tupleable[T] extends (T => Product)
sealed class ValueTupler[T] extends Tupleable[T] {
def apply(x: T) = Tuple1(x)
}
sealed class TupleTupler[T <: Product] extends Tupleable[T] {
def apply(x: T) = x
}
// implicit conversions
trait LowPriorityTuple {
// this provides a Tupleable[T] for any type T, but is the
// lowest priority conversion
implicit def anyIsTupleable[T]: Tupleable[T] = new ValueTupler
}
object Tupleable extends LowPriorityTuple {
implicit def tuple2isTuple[T1, T2]: Tupleable[Tuple2[T1,T2]] = new TupleTupler
implicit def tuple3isTuple[T1, T2, T3]: Tupleable[Tuple3[T1,T2,T3]] = new TupleTupler
// ... etc ...
}
Вы можете использовать этот класс типов в своем API следующим образом:
def m[T: Tupleable](v: T) = {
val p = implicitly[Tupleable[T]](v)
// ... do something with p
}
Если ваш метод возвращает продукт, вы можете увидеть, как применяются преобразования:
scala> def m[T: Tupleable](v: T) = implicitly[Tupleable[T]](v)
m: [T](v: T)(implicit evidence$1: Tupleable[T])Product
scala> m("asdf") // as Tuple1
res12: Product = (asdf,)
scala> m(Person("a", "n")) // also as Tuple1, *not* as (String, String)
res13: Product = (Person(a,n),)
scala> m((1,2)) // as Tuple2
res14: Product = (1,2)