代码之家  ›  专栏  ›  技术社区  ›  Joshua

我可以在scala中重载括号吗?

  •  8
  • Joshua  · 技术社区  · 14 年前

    试图找出如何重载类上的括号。

    我有这个代码:

    class App(values: Map[String,String])
    {
      // do stuff
    }
    

    我希望能够通过以下方式访问值映射:

    var a = new App(Map("1" -> "2"))
    a("1") // same as a.values("1")
    

    这有可能吗?

    4 回复  |  直到 7 年前
        1
  •  20
  •   sepp2k    14 年前

    您需要定义 apply 方法。

    class App(values: Map[String,String]) {
      def apply(x:String) = values(x)
      // ...
    }
    
        2
  •  9
  •   Dave Griffith    14 年前

    为了完整性起见,应该说您的“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族语言中必须特殊使用的东西(例如数组元素分配和获取)建议额外的语法。它还可以方便地用于伙伴对象的工厂方法。除此之外,还应该小心,因为这是很容易使您的代码过于紧凑而不能真正可读的事情之一。

        3
  •  5
  •   Rex Kerr    14 年前

    正如其他人已经注意到的,您希望过载 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
  •  4
  •   Community Mr_and_Mrs_D    7 年前

    我认为它可以使用apply: How does Scala's apply() method magic work?