我正在研究Learning Scala一书中的一个问题,它要求你创建一个输入为2元组的函数,如果任何一个值为int
,则返回{{1} } tuple
在第一个位置。如果它们是相同的类型,我有一些工作,但无法弄清楚如何使类型足够灵活接受任何输入,然后处理可能被切换的返回值。我来自Python背景,所以我只是学习如何强制执行这些事情:)
int
答案 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)
同样作为提示:大多数情况下,您发现自己要使用isInstanceOf
或asInstanceOf
考虑您要完成的工作,并考虑使用模式匹配。
这可能不是问题所在,但您也可以使用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)