呼叫“a”;“静态功能”;在Scala中属于泛型类型
我试图用Scala表示另一种语言的片段。我希望所有类都有一个表示其类型的自定义字符串值。当涉及到容器类时,我遇到了麻烦呼叫“a”;“静态功能”;在Scala中属于泛型类型,scala,generics,Scala,Generics,我试图用Scala表示另一种语言的片段。我希望所有类都有一个表示其类型的自定义字符串值。当涉及到容器类时,我遇到了麻烦 如何根据MyContainerClass[T的泛型参数获取typeName,这类事情通常是通过类型类完成的: trait TypeName[T] { def typeName: String } implicit object MyString extends TypeName[MyString] { def typeName = "mystring" } impl
如何根据MyContainerClass[T的泛型参数获取
typeName
,这类事情通常是通过类型类完成的:
trait TypeName[T] {
def typeName: String
}
implicit object MyString extends TypeName[MyString] {
def typeName = "mystring"
}
implicit object MyInt extends TypeName[MyInt] {
def typeName = "myint"
}
class MyString(val underlying: String) extends MyType {
val typeName = MyString.typeName
}
class MyInt(val underlying: Int) extends MyType {
val typeName = MyInt.typeName
}
class MyContainerClass[T <: MyType : TypeName](
val underlying: Seq[T]
) extends MyType {
val typeName = implicitly[TypeName[T]].typeName + "[]"
}
trait TypeName[T]{
def typeName:String
}
隐式对象MyString扩展TypeName[MyString]{
def typeName=“mystring”
}
隐式对象MyInt扩展类型名[MyInt]{
def typeName=“myint”
}
类MyString(val底层:String)扩展了MyType{
val typeName=MyString.typeName
}
类MyInt(val-underlined:Int)扩展了MyType{
val typeName=MyInt.typeName
}
类MyContainerClass[T我认为@Dima的答案很好,我实际上是在写同样的代码,但他比我快。因此,我将提供另一种解决方案。如果您同意使用真实的类名:
import scala.reflect._
object MyLang {
trait MyType {
val typeName = this.getClass.getName
}
class MyString(val underlying: String) extends MyType
class MyInt(val underlying: Int) extends MyType
class MyContainerClass[T <: MyType](val underlying: Seq[T])
(implicit tag: ClassTag[T])
extends MyType {
override val typeName = s"${getClass.getName}[${tag.runtimeClass.getName}]"
}
}
您甚至可以将typeName
定义为元组(父类、子类)
或任何其他包含java.lang.class[\u]
的非字符串数据类型
问题实际上是Scala不允许您覆盖静态方法,因为它没有这些方法。您可以在某种程度上用对象方法模拟它们
在您的例子中,您试图使用一个实例变量typeName
,但您无法从类中获取它,因为它不是实例。在这种情况下,您需要一些位置来保存该值,如@Dima的answer-object中,您根据类型隐式查找该对象。缺点是您必须为每种类型创建它们 对于只寻找已接受答案的最小实现的任何人来说,只需要定义一些traitY[T]
、类Z
、以及扩展Y
的隐式对象Z
:
object TypeClassTest {
trait X
trait Y[T] {
def t: T
}
// Class with "static" method `t`
class Z extends X
// "static" method defined
implicit object Z extends Y[String] {
override def t = "t"
}
// Using 'static' method of the generic type
class A[T <: X : Y](underlying: T) {
val t: T = implicitly[Y[T]].t
}
}
对象类型类测试{
性状X
性状Y[T]{
定义t:t
}
//使用“静态”方法初始化`t`
类Z扩展了X
//定义的“静态”方法
隐式对象Z扩展Y[字符串]{
覆盖def t=“t”
}
//使用泛型类型的“静态”方法
class A[T你可以只做tag.toString
。这和我的解决方案实际上是一样的:ClassTag
扮演着类型class的角色。“pro”是指它已经为每个类定义了,当然是“con”,你不能自定义名称。
scala> new MyLang.MyContainerClass(Seq(new MyLang.MyString("abc"))).typeName
res0: String = MyLang$MyContainerClass[MyLang$MyString]
object TypeClassTest {
trait X
trait Y[T] {
def t: T
}
// Class with "static" method `t`
class Z extends X
// "static" method defined
implicit object Z extends Y[String] {
override def t = "t"
}
// Using 'static' method of the generic type
class A[T <: X : Y](underlying: T) {
val t: T = implicitly[Y[T]].t
}
}