Scala 隐式类和继承

标签 scala inheritance

假设我想向 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"
}

现在我的客户端代码如下所示:
def someMethod(strategy: StringExtensions) : String{
  val name = "Pawel"
  return strategy.doSth(name)
}
...
String ret = someMethod(new Strategy1())

但我想要这样的代码:
def someMethod(strategy: StringExtensions) : String{
  val name = "Pawel"
  return name.doSth() // Here is the tricky line
}
...
String ret = someMethod(new Strategy1())

我玩了一些隐式,但是当涉及到这个带有继承的用例时,我找不到合适的解决方案,有什么帮助吗?

最佳答案

我不确定您是否真的应该使用这样的隐式,但也许在某些 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())

正如评论中提到的,另一种编码是这样的:
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())

关于Scala 隐式类和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40996578/

相关文章:

scala - 存在类型如何与路径依赖类型重叠?

scala - Spark 卡拉: Performance degrade with simple UDF over large number of columns

scala - 使用 Play Scala 使用 Iteratees 将文件直接逐 block 上传到 S3

c++ - 接口(interface)变化 : add new arguments to abstract c++ method

scala - 如何使用scala规范化或标准化spark中具有多个列/变量的数据?

将迭代的每个元素与另一个元素的每个元素组合的Scala方法?

c# - 如何从子类向基类的字段添加属性?

ios - 在父类(super class)中声明一个可以被子类访问的 block

c# - 在数据类型和调用匹配方法之间进行选择?

Java:如果我们必须自己实现抽象方法,实现多个接口(interface)如何实现多重继承?