简体   繁体   English

如何在泛型类中引用伴随对象的方法?

[英]How can I reference a companion object's method in a generic class?

So I am a bit new to scala.所以我对 Scala 有点陌生。

How does one write scala code to reference a method from case class's companion object in a generic fashion?如何编写 Scala 代码以通用方式从案例类的伴随对象中引用方法? I have tried a couple of different approaches and can't seem to find one that works.我尝试了几种不同的方法,但似乎找不到一种有效的方法。

Below is some sample code that works, but I have to manually build each subclass.下面是一些有效的示例代码,但我必须手动构建每个子类。

For example:例如:

class One extends Act[LetterA] {
    val intro = LetterA.sayhi
}

I would much rather do something like:我更愿意做这样的事情:

class AllOfThem[T <: LettersClass, S <: LettersSingleton] extends Act[T] {
   val intro = S.sayhi
}

but I can't seem to find syntax that works or will compile.但我似乎无法找到有效或将编译的语法。 What is the proper way to do this, or am I looking for something that is not supported in the language?这样做的正确方法是什么,还是我正在寻找该语言不支持的东西? I recognise I am probably a little off on how I am structuring my classes and traits, but I am not sure how to best tackle this desired behaviour.我意识到我可能对我如何构建我的类和特征有点偏离,但我不确定如何最好地解决这种期望的行为。

Additionally, is there a way to something similar to what I have commented out in the method 'actionTwo' in the Act class?另外,有没有办法类似于我在 Act 类的方法“actionTwo”中注释的内容?

Sample Code listing:示例代码清单:

trait LettersSingleton {
   def sayhi() : String
}

trait LettersClass {
   val id : Int
}

// trait Letters extends LettersClass with LettersSingleton {  }


object LetterA extends LettersSingleton {
   def sayhi = "Hi I am A"
}

object LetterB extends LettersSingleton {
   def sayhi = "Hi I am B"
}

case class LetterA( val id : Int ) extends LettersClass { }
case class LetterB( val id : Int, val name:String ) extends LettersClass { }


abstract class Act[ T <: LettersClass ]  {

   val intro : String

   def actionOne( a : T ) = {
       println( a.id + " is my id" )
   }

   def actionTwo() = {
//       println( T.sayhi )
   }
}

class One extends Act[LetterA] {
    val intro = LetterA.sayhi
}

class Two extends Act[LetterB] {
    val intro = LetterB.sayhi
}

So you can't do exactly what you want, but you can get very close with the commonly used typeclass pattern:所以你不能完全按照你的意愿去做,但是你可以非常接近常用的类型类模式:

//add a type parameter, now you have a typeclass
trait LettersSingleton[T] {
   def sayhi() : String
}

//LettersClass stays the same

object Implicits {
  //implicit classes/objects have to go inside an object

  //create typeclass instances as implicit objects
  implicit object LetterASingleton extends LettersSingleton[LetterA] {
     def sayhi = "Hi I am A"
  }

  implicit object LetterBSingleton extends LettersSingleton[LetterB] {
     def sayhi = "Hi I am B"
  }
}

import Implicits._

//add an implicit parameter to the class
abstract class Act[ T <: LettersClass ](implicit singleton: LettersSingleton[T])  {

   def actionTwo() = {
       println( singleton.sayhi )
   }
}

(new Act[LetterA]).actionTwo() //prints "Hi I am A"
(new Act[LetterB]).actionTwo() //prints "Hi I am B"

So basically what happens is any time you create a new Act[T] , the compiler is going to try to fill in the implicit parameter for you by looking for any implicit objects or vals of the correct type in scope.所以基本上发生的事情是任何时候你创建一个新的Act[T] ,编译器都会尝试通过在范围内查找任何隐式对象或正确类型的值来为你填充隐式参数。 So所以

val a = new Act[LetterA]

will actually become实际上会变成

val a = new Act[LetterA](LetterASingleton)

You'll notice that the singletons are no longer the companion objects of the case classes, which is fine.您会注意到单例不再是 case 类的伴生对象,这很好。 You have to define a trait regardless, so it doesn't make much different whether it's the companion object or some other object that implements it.无论如何,您都必须定义特征,因此无论是伴随对象还是实现它的其他对象,都没有太大区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何保证伴随对象中存在方法并对其进行引用? - How can I guarantee the existence of a method in a companion object and reference it? 如何为Java提供Scala随播对象的类? - How can I provide a scala companion object's class to Java? 无法从伴随对象访问伴随类的方法 - Can't access method of companion class from companion object 随播对象的类 - Companion object's class 在Scala中,如何为Java中定义的类定义伴随对象? - In Scala, how can I define a companion object for a class defined in Java? 如何从 class 名称中获得伴侣 object? - How can I get companion object from a class name? 通用特征取一个类,它的伴随对象作为类型参数 - generic trait taking a class and it's companion object as a type parameter 创建一个伴随对象,该对象混合了一个特性,该特性定义了一个方法,该方法返回对象的伴随类的对象 - Create a companion object that mixes in a trait that defines a method which returns an object of the object's companion class 在Scala中的伴随对象的apply方法中实例化类的子类型 - Instantiating a class's subtype in the companion object's apply method in Scala 为什么我不能在Scala中的类的伴随对象中访问私有类方法? - Why can't I access private class methods in the class's companion object in Scala?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM