限制隐式参数解析范围

时间:2013-05-02 16:30:11

标签: scala

我经常发现我需要用内部递归辅助函数编写函数,并且它的外部函数采用相同的参数列表,但只有一个额外的累加器参数:

def encode(tree : Tree, text: String):String = {
    def rec(tree: Tree, text:String, result:String):String = ???

    rec(tree, text, "")
} 

我想将其简化为:

def encode(tree : Tree, text: String)(implicit result:String = "" ):String

这可以删除内部函数定义,但它有一个问题,看看我是否需要在lookup内调用函数encodelookup也采用隐式参数键入String,implicit result:String = ""隐式传递给lookup函数。

 def lookup(tree : Tree, text: String)(implicit result:String = "" ):String

我不希望发生这种情况,是否有办法限制lookup中的隐式参数解析该函数​​之外?还是其他更好的想法?

3 个答案:

答案 0 :(得分:2)

如何使用普通的默认参数,然后在实现中显式传递累加器:

def encode(tree : Tree, text: String, result : String = "" ): String = {
  //snip
  encode(new_tree, new_text, new_result)
}

// call
encode(my_tree, my_text)

答案 1 :(得分:0)

您是否考虑在该方案中明确提供隐式lookup。像这样:

def encode(tree : Tree, text: String)(implicit result:String = "" ):String = {
  lookup(tree, text)("other string")
}

答案 2 :(得分:0)

你的想法很好但不鼓励使用这种通用类型的隐式参数,以免你偶然发现隐式定义冲突(例如,你的范围内可见的隐式Strings太多了。)

IIRC,马丁的这本书特别提到了这些问题。

您可以围绕String定义一个显式的Wrapper层次结构类,其类型会针对每个特定方法进行更改

abstract class Wrapper[A](value: A) { def apply(): A = value }

case class EncodeWrapper[A](value: A) extends Wrapper(value)
case class LookupWrapper[A](value: A) extends Wrapper(value)

def encode(tree : Tree, text: String)(implicit result: EncodeWrapper[String] = EncodeWrapper("") ):String

def lookup(tree : Tree, text: String)(implicit result: LookupWrapper[String] = LoodupWrapper("") ):String

有明显的缺点,你需要“包装/解包”方法体中的String。

这可以通过方法中包装器和包装类型之间的隐式转换来缓解,但它仍然有点笨拙,特别是对于非常紧凑的辅助函数...

当然,当方法的返回类型更具体且隐式碰撞的可能性非常低时,一切都会简化。