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