Мне не очень-то хорошо, когда я всегда повторяю определение строкового кортежа каждый раз, когда мне это нужно. Могу я просто назвать его и использовать как имя типа? Было бы неплохо называть его поля, а не использовать._1,._2 и т.д.
Можно ли назвать кортеж (определить структуру?) В Scala 2.8?
Ответ 1
Что касается вашего первого вопроса, вы можете просто использовать псевдоним типа:
type KeyValue = (Int, String)
И, конечно, Scala - это объектно-ориентированный язык, поэтому в отношении вашего второго вопроса о том, как специализировать кортеж, магическое слово является наследованием:
case class KeyValue(key: Int, value: String) extends (Int, String)(key, value)
Что это. Класс не нуждается даже в теле.
val kvp = KeyValue(42, "Hello")
kvp._1 // => res0: Int = 42
kvp.value // => res1: String = "Hello"
Обратите внимание, однако, что наследование классов case (которое Tuple2
есть), устарело и может быть запрещено в будущем. Здесь предупреждение о компиляторе вы получите для определения вышеуказанного класса:
предупреждение: класс case
class KV
имеет предка класса классаclass Tuple2
. Это было устаревшим для чрезмерного усложнения как использования, так и реализации. Вместо этого вы должны использовать экстракторы для сопоставления шаблонов на нелистных узлах.
Ответ 2
Тип псевдонима подходит для наименования вашего Tuple, но вместо этого попробуйте использовать класс case. Вы сможете использовать именованные параметры
Пример с кортежем:
def foo(a : Int) : (Int, String) = {
(a,"bar")
}
val res = foo(1)
val size = res._1
val name= res._2
С классом case:
case class Result( size : Int , name : String )
def foo(a : Int) : Result = {
Result(a,"bar")
}
val res = foo(1)
val size = res.size
val name= res.name
Ответ 3
Вот решение, которое создает псевдоним типа и объект factory.
scala> type T = (Int, String)
defined type alias T
scala> object T { def apply(i: Int, s: String): T = (i, s) }
defined module T
scala> new T(1, "a")
res0: (Int, String) = (1,a)
scala> T(1, "a")
res1: (Int, String) = (1,a)
Как уже упоминалось, вы, вероятно, должны просто создать класс case.
Ответ 4
Хотя, как говорили другие, явные (случайные) классы лучше всего в общем смысле.
Однако для локализованных сценариев вы можете использовать экстрактор кода, чтобы улучшить читаемость кода:
val (first, second) = incrementPair(3, 4)
println(s"$first ... $second")
Для метода, возвращающего кортеж:
def incrementPair(pair: (Int, Int)) : (Int, Int) = {
val (first, second) = pair
(first + 1, second + 1)
}