我可以在 Scala 2.8 中命名一个元组(定义一个结构?)吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3687806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:25:27  来源:igfitidea点击:

Can I name a tuple (define a structure?) in Scala 2.8?

scalasyntaxtypes

提问by Ivan

It does not look very good for me to always repeat a line-long tuple definition every time I need it. Can I just name it and use as a type name? Would be nice to name its fields also instead of using ._1, ._2 etc.

每次需要时总是重复一行长的元组定义对我来说看起来不太好。我可以只命名它并用作类型名称吗?也可以命名其字段而不是使用 ._1、._2 等。

回答by J?rg W Mittag

Regarding your first question, you can simply use a type alias:

关于您的第一个问题,您可以简单地使用类型别名:

type KeyValue = (Int, String)

And, of course, Scala is an object-oriented language, so regarding your second about how to specialize a tuple, the magic word is inheritance:

而且,当然,Scala 是一种面向对象的语言,所以关于如何特化元组的第二个方面,神奇的词是继承

case class KeyValue(key: Int, value: String) extends (Int, String)(key, value)

That's it. The class doesn't even need a body.

而已。这个类甚至不需要一个身体。

val kvp = KeyValue(42, "Hello")
kvp._1    // => res0: Int    = 42
kvp.value // => res1: String = "Hello"

Note, however, that inheriting from case classes (which Tuple2is), is deprecated and may be disallowed in the future. Here's the compiler warning you get for the above class definition:

但是请注意,从案例类(即Tuple2)继承已被弃用,将来可能会被禁止。这是您为上述类定义获得的编译器警告:

warning: case class class KVhas case class ancestor class Tuple2. This has been deprecated for unduly complicating both usage and implementation. You should instead use extractors for pattern matching on non-leaf nodes.

警告:案例类class KV具有案例类祖先class Tuple2。这已被弃用,因为它使使用和实现变得过于复杂。您应该改为使用提取器在非叶节点上进行模式匹配。

回答by Steve Gury

Type alias is fine for naming your Tuple, but try using a case class instead. You will be able to use named parameters

类型别名很适合命名元组,但请尝试使用 case 类。您将能够使用命名参数

Example with tuple:

元组示例:

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

With a case class:

使用案例类:

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

回答by retronym

Here's a solution that creates a type alias and a factory object.

这是一个创建类型别名和工厂对象的解决方案。

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)

However as others have mentioned, you probably should just create a case class.

但是,正如其他人所提到的,您可能应该只创建一个案例类。

回答by StuartLC

Although as others have said, explicit (case) classes are best in the general sense.

尽管正如其他人所说,显式(案例)类在一般意义上是最好的。

However for localized scenarios what you can do is to use the tuple extractorto improve code readability:

但是对于本地化场景,您可以做的是使用元组提取器来提高代码可读性:

val (first, second) = incrementPair(3, 4)
println(s"$first ... $second")

Given a method returning a tuple:

给定一个返回元组的方法:

def incrementPair(pair: (Int, Int)) : (Int, Int) = {
  val (first, second) = pair
  (first + 1, second + 1)
}