在Scala中,我能否重载括号?

8
尝试弄清如何在类上重载圆括号。
我有以下代码:
class App(values: Map[String,String])
{
  // do stuff
}

我希望能够通过以下方式访问值Map:
var a = new App(Map("1" -> "2"))
a("1") // same as a.values("1")

这是可能的吗?
4个回答

20

你需要定义一个apply方法。

class App(values: Map[String,String]) {
  def apply(x:String) = values(x)
  // ...
}

9

为了完整起见,应该说你的“apply”可以取多个值,并且“update”作为“apply”的对偶,允许在赋值的左侧进行“括号重载”。

Class PairMap[A, B, C]{
   val contents: mutable.Map[(A,B), C]  = new mutable.Map[(A, B), C]();
   def apply(a:A, b:B):C = contents.get((a, b))
   def update(a:A, b:B, c:C):Unit = contents.put((a, b), c)
}

val foo = new PairMap[String, Int, Int]()
foo("bar", 42) = 6
println(foo("bar", 42)) // prints 6

所有这些的主要价值在于它防止人们为早期C系列语言中必须特殊处理的事物(例如数组元素赋值和提取)建议额外的语法。它也很方便用于伴生对象上的工厂方法。除此之外,需要注意的是,它是那种容易使您的代码过于紧凑而实际上难以阅读的东西之一。

5

正如其他人已经指出,您想要重载 apply

class App(values: Map[String,String]) {
  def apply(s: String) = values(s)
}

在此过程中,您可能还希望重载伴生对象的apply方法:

object App {
  def apply(m: Map[String,String]) = new App(m)
}

然后你可以:
scala> App(Map("1" -> "2"))  // Didn't need to call new!
res0: App = App@5c66b06b

scala> res0("1")
res1: String = 2

尽管这是否有益还是令人困惑,取决于您试图做什么。

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接