如何使用Type Parameter来处理元组中的任何类型?

时间:2017-01-03 20:14:26

标签: scala

我正在研究Learning Scala一书中的一个问题,它要求你创建一个输入为2元组的函数,如果任何一个值为int,则返回{{1} } tuple在第一个位置。如果它们是相同的类型,我有一些工作,但无法弄清楚如何使类型足够灵活接受任何输入,然后处理可能被切换的返回值。我来自Python背景,所以我只是学习如何强制执行这些事情:)

int

2 个答案:

答案 0 :(得分:3)

类型(A, A)意味着元组的两个元素具有相同的类型。换句话说,它会接受(0, 0)("hello", "world"),但不接受("hello", 15)。您可以使用类型(A, B)修复此问题。

之后,查看其中任何一个元素是Int的最简洁最简单的方法可能是使用模式匹配而不是.isInstanceOf[Int]检查。

答案 1 :(得分:1)

重复我的评论:通过说x: (A, A),你说输入元组x在两个位置都必须具有相同的类型。因此,它不能接受("hello", 15)因为类型不同。

现在要真正解决问题,我能想到的唯一解决方案是使用返回类型(Any, Any)

scala> def intInFirst[A, B](x: (A, B)): (Any, Any) = 
     | x match {
     | case (_, b: Int) => x.swap
     | case _ => x
     | }
intInFirst: [A, B](x: (A, B))(Any, Any)

scala> intInFirst((1,2))
res2: (Any, Any) = (2,1)

scala> intInFirst((1,"apple"))
res4: (Any, Any) = (1,apple)

scala> intInFirst(("apple",1))
res5: (Any, Any) = (1,apple)

同样作为提示:大多数情况下,您发现自己要使用isInstanceOfasInstanceOf考虑您要完成的工作,并考虑使用模式匹配。

编辑:

这可能不是问题所在,但您也可以使用Either作为返回类型:

scala> :pa
// Entering paste mode (ctrl-D to finish)

def intInFirst[A, B](x: (A, B)): Either[(B, A), (A, B)] =
    x match {
        case (_, b: Int) => Left(x.swap)
        case _ => Right(x)
    }

// Exiting paste mode, now interpreting.

intInFirst: [A, B](x: (A, B))Either[(B, A),(A, B)]

scala> intInFirst((1,"apple"))
res1: Either[(String, Int),(Int, String)] = Right((1,apple))

scala> intInFirst((1,2))
res2: Either[(Int, Int),(Int, Int)] = Left((2,1))

Either很有意思,因为您可以在输出上进行模式匹配,以找出使用的是哪种情况:

scala> :pa
// Entering paste mode (ctrl-D to finish)

intInFirst((1,2)) match {
    case Left(a) => s"This value was swapped: $a"
    case Right(a) => s"This value was not swapped: $a"
}

// Exiting paste mode, now interpreting.

res3: String = This value was swapped: (2,1)

scala> :pa
// Entering paste mode (ctrl-D to finish)

intInFirst((1,"apple")) match {
    case Left(a) => s"This value was swapped: $a"
    case Right(a) => s"This value was not swapped: $a"
}

// Exiting paste mode, now interpreting.

res4: String = This value was not swapped: (1,apple)