Упаковка scala tuple в пользовательский объект класса

У меня есть кортеж

val tuple = ("Mike", 40)

и класс case

case class Person(name: String, age: Int)

Как я могу упаковать свой кортеж в объект класса Person? Существуют ли какие-либо способы, кроме этого:

new Person(tuple._1, tuple._2)

Возможно, что-то вроде

tuple.asInstanceOf[Person]

Спасибо.

Ответ 1

tupled

Вы можете преобразовать метод Person.apply в функцию, а затем использовать метод tupled для функции:

(Person.apply _) tupled tuple

В scala 2.11.8 и scala 2.12 объект-компаньон case class extends FunctionN, поэтому этого будет достаточно:

Person tupled tuple

Соответствие шаблону

Аналогом new Person(tuple._1, tuple._2) без уродливых методов _N является сопоставление с образцом:

tuple match { case (name, age) => Person(name, age) }

Ответ 2

Маленькая версия "только для удовольствия", которая может быть абстрагирована далее. Конечно, с небольшой помощью shapeless:

  import shapeless._
  import Tuples._

  case class Person(name: String, age: Int)
  val tup = ("Alex", 23)

  val personIso = Iso.hlist(Person.apply _, Person.unapply _)

  personIso.from(tup.hlisted)

Ответ 3

Вы можете определить неявный, который выполняет преобразование. Я использую это в своих параметризованных тестах для улучшения удобочитаемости.

// Define adults with tuples
implicit def makePerson(in:(String,Int))=new Person(in._1,in._2);
// Define kids with triples
implicit def makeUnderagePerson(in:(String, Int, String))=new Person(in._1,in._2, new Person(in._3));

//create single person:
val person:Person=("Mike", 40)

//crate a list of persons:
//
//Remember to type the list, this is what forces the implicit on each tuple.
//                     ||
//                     \/
val personList=List[Person](
("Mike", 40),
("Jane", 41),
("Jack", 42),
// Uses the implicit ment for kids. 
("Benjamin", 5, Jack)
);

Мне нравится этот lanuage.