Scala隐式类和继承

Paw*_*ski 3 inheritance scala

假设我想在String类中添加一些方法.但是应该应用的具体隐式类在运行时(策略模式)中是已知的.让我们说

trait StringExtensions {
  def doSth(str: String): String
}

class Strategy1 extends StringExtensions {
   override def doSth(str: String): String = "a"
}

class Strategy2 extends StringExtensions {
   override def doSth(str: String): String = "b"
}
Run Code Online (Sandbox Code Playgroud)

现在我的客户端代码如下:

def someMethod(strategy: StringExtensions) : String{
  val name = "Pawel"
  return strategy.doSth(name)
}
...
String ret = someMethod(new Strategy1())
Run Code Online (Sandbox Code Playgroud)

但我希望代码如下:

def someMethod(strategy: StringExtensions) : String{
  val name = "Pawel"
  return name.doSth() // Here is the tricky line
}
...
String ret = someMethod(new Strategy1())
Run Code Online (Sandbox Code Playgroud)

我玩了一些implicits但是当涉及到继承的这个用例时,我找不到合适的解决方案,任何帮助?

Jas*_*r-M 5

我不确定你是否真的应该使用这样的含义,但也许在某些DSL中这可能是一个有效的用例.

class StringExtensions(str: String, strategy: StringExtensionsStrategy) {
  def doSth() = strategy.doSth(str)
}

trait StringExtensionsStrategy extends (String => StringExtensions) {
  final def apply(str: String) = new StringExtensions(str, this)
  def doSth(str: String): String
}

class Strategy1 extends StringExtensionsStrategy {
   override def doSth(str: String) = "a"
}

class Strategy2 extends StringExtensionsStrategy {
   override def doSth(str: String) = "b"
}

def someMethod(implicit strategy: StringExtensionsStrategy) = {
  val name = "Pawel"
  name.doSth()
}

val ret: String = someMethod(new Strategy1())
Run Code Online (Sandbox Code Playgroud)

正如评论中所提到的,另一种编码方式是:

class StringExtensions(str: String, strategy: StringExtensionsStrategy) {
  def doSth() = strategy.doSth(str)
}

trait StringExtensionsStrategy {
  implicit final def apply(str: String) = new StringExtensions(str, this)
  def doSth(str: String): String
}

class Strategy1 extends StringExtensionsStrategy {
   override def doSth(str: String) = "a"
}

class Strategy2 extends StringExtensionsStrategy {
   override def doSth(str: String) = "b"
}

def someMethod(strategy: StringExtensionsStrategy) = {
  import strategy._
  val name = "Pawel"
  name.doSth()
}

val ret: String = someMethod(new Strategy1())
Run Code Online (Sandbox Code Playgroud)