метод с угловыми скобками (<>) - PullRequest
14 голосов
/ 04 июля 2011

Можно ли иметь угловые скобки в именах методов, например, :

class Foo(ind1:Int,ind2:Int){...}
var v = new Foo(1,2)
v(1) = 3 //updates ind1
v<1> = 4 //updates ind2

Реальная ситуация, очевидно, более сложная, чем эта !! Я пытаюсь предоставить удобный пользовательский интерфейс.

Ответы [ 3 ]

38 голосов
/ 04 июля 2011

Этот ответ не означает, что он слишком серьезен, и является лишь доказательством того, что этого можно достичь, используя некоторые хаки.

class Vector(values: Int*) {
  val data = values.toArray
  def < (i:Int) = new {
    def `>_=`(x: Int) {
      data(i) = x
    }
    def > {
      println("value at "+ i +" is "+ data(i))
    }
  }
  override def toString = data.mkString("<", ", ", ">")
}

val v = new Vector(1, 2, 3)
println(v) // prints <1, 2, 3>
v<1> = 10
println(v) // prints <1, 10, 3>
v<1> // prints: value at 1 is 10

Используя этот класс, мы можем получить вектор, который использует <> вместо () для «чтения» и доступа для записи. Компилятор (2.9.0.1) падает, если > возвращает значение. Это может быть ошибка или результат неправильного использования >.

6 голосов
/ 04 июля 2011

Редактировать: Я был не прав;Ответ kassens показывает, как сделать это так, как вы хотите.


Невозможно реализовать метод, который будет вызываться при написании v<1> = 4 (кроме, может быть, если вы пишете плагин компилятора?).Однако, что-то вроде этого было бы возможно:

class Foo {
  def at(i: Int) = new Assigner(i)
  class Assigner(i: Int) {
    def :=(v: Int) = println("assigning " + v + " at index " + i)
  }
}

Тогда:

val f = new Foo
f at 4 := 6
1 голос
/ 04 июля 2011

С небольшой хитростью вы действительно можете получить довольно близко к тому, что вы хотите.

object Foo {
  val a:Array[Int] = new Array(100)
  def <(i:Int) = new Updater(a, i)
}

class Updater(a:Array[Int], i:Int) {
  def update(x:Int) {
    a(i) = x
  }
  def >() = this
}

Foo<1>() = 123

Я не уверен, почему Scala требует ().И да, это что-то вроде хака ...

...