使用与参数类型相同的类型参数和带有匹配表达式的参数类型 [英] Using same type parameter as argument type and parameter type with match expression
问题描述
通过编译以下示例代码会出错.
I get errors by compiling following example code.
abstract class Base
case class A(i: Int) extends Base
case class B(s: String) extends Base
class Transform {
def func[T <: Base](arg: T): T = arg match {
case A(i) => A(i)
case B(s) => B(s)
}
}
错误是
Example.scala:9: error: type mismatch;
found : A
required: T
case A(i) => A(i)
^
Example.scala:10: error: type mismatch;
found : B
required: T
case B(s) => B(s)
^
two errors found
这些错误是合理的.
为避免这种情况,我需要将 asInstanceOf [T]
放在类似于 A(i).asInstanceOf [T]
的实例化后面.但是,如果有很多区分大小写的模式,那么对所有返回值都这样做是很烦人的.
These errors are reasonable.
To avoid this, I need to put asInstanceOf[T]
behind instantiation like A(i).asInstanceOf[T]
. However, it is annoying to do like that for all return value if there are a lot of match case patterns.
此外,我想使用 Transform
类作为父类,并覆盖 func()
来执行特定的操作,例如下面的代码.
In addition, I want to use Transform
class as parent class and override func()
to execute specific operation like below code.
class ExtTransform extends Transform {
override def func[T <: Base](arg: T): T = arg match {
case A(i) => A(i + 1)
case _ => super.func(arg)
}
}
有更好的方法或技巧吗?
Are there better ways or some trick?
推荐答案
为避免这种情况,我需要将asInstanceOf [T]放在实例化之后,例如A(i).asInstanceOf [T].但是,如果有很多区分大小写的模式,那么对所有返回值都这样做是很烦人的.
To avoid this, I need to put asInstanceOf[T] behind instantiation like A(i).asInstanceOf[T]. However, it is annoying to do like that for all return value if there are a lot of match case patterns.
嗯,这个问题很简单:在比赛结束时将它放在一个位置,而不是每个分支.
Well, that problem is an easy one: put it in one place at the end of the match instead of every branch.
override def func[T <: Base](arg: T): T = (arg match {
case A(i) => A(i)
case B(s) => B(s)
}).asInstanceOf[T]
但是请注意,您的设计本质上是不安全的,因为除了 Base
, A
和 B
:单例类型( a.type
),复合类型(<带有SomeTrait的 A
), Null
...以及它们中的任何一个都可以用作 T
.最好有过载:
But please note your design is inherently unsafe because there are subtypes of Base
other than Base
, A
, and B
: singleton types (a.type
), compound types (A with SomeTrait
), Null
... and any of them can be used as T
. It may be better just to have overloads:
class Transform {
def func(arg: Base): Base = arg match {
case arg: A => func(arg)
case arg: B => func(arg)
}
def func(arg: A): A = arg
def func(arg: B): B = arg
}
class ExtTransform extends Transform {
override def func(arg: A): A = A(arg.i + 1)
}
这篇关于使用与参数类型相同的类型参数和带有匹配表达式的参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!