Могу ли я назвать кортеж (определить структуру?) В Scala 2.8? - PullRequest
19 голосов
/ 10 сентября 2010

Для меня не очень хорошо всегда повторять определение кортежа длиной в строку каждый раз, когда мне это нужно. Могу ли я просто назвать его и использовать в качестве имени типа? Было бы неплохо также назвать его поля вместо использования ._1, ._2 и т. Д.

Ответы [ 4 ]

32 голосов
/ 10 сентября 2010

Что касается вашего первого вопроса, вы можете просто использовать псевдоним типа:

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"

Обратите внимание, однако, что наследование от классов прецедентов (которые Tuple2) являются устаревшими и может быть запрещено в будущем.Вот предупреждение компилятора, которое вы получаете для приведенного выше определения класса:

предупреждение: у класса class KV есть предок класса class Tuple2.Это не рекомендуется из-за чрезмерного усложнения как использования, так и реализации.Вместо этого вы должны использовать экстракторы для сопоставления с образцом на неконечных узлах.

18 голосов
/ 10 сентября 2010

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

Пример с кортежем:

def foo(a : Int) : (Int, String) = {
  (a,"bar")
}
val res = foo(1)
val size = res._1
val name= res._2

С классом корпуса:

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
4 голосов
/ 11 сентября 2010

Вот решение, которое создает псевдоним типа и объект фабрики.

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.

1 голос
/ 06 марта 2016

Хотя, как уже говорили другие, явные (case) классы являются лучшими в общем смысле.

Однако для локализованных сценариев вы можете использовать экстрактор кортежей для улучшения читабельности кода:

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...