2014-10-07 8 views
8

Ich möchte ein paar funky Schließung-wie Zeug machen. Ich möchte, dass eine Methode ein anonymes Objekt zurückgibt, dessen Eingeweide auf die Parameter der Methode verweisen. Hier ist der Code, den ich schrieb, dass meine Absicht zeigt:Scala-Funktion, die ein anonymes Objekt zurückgibt?

object SessionManagement { 

    implicit class SessionManagementExtensions(val c : ChainBuilder) { 

    def set(dest: String) = object { 

     def from(src: String) = 
     c.exec(session => { 
      val list = session(src).as[Vector[String]] 
      val i = if (list.size == 0) -1 else Random.nextInt(list.size) 
      val value = if (i > 0) list(i) else "INVALID_" + dest 
      session.set(dest, value) 
     }) 

     def to[T](v: Expression[T]) = 
     c.exec(session => session.set(dest, v)) 

    } 

} 

, was ich versuche zu tun ist, einen Anruf müssen „set“ zurückgeben ein Objekt, das mir erlaubt, dann ist die Kette zusammen einen Aufruf an“.to “, etwa so:

.set(SOMETHING).to(OTHER) 

Aber ich kann nicht sagen,

def foo = object { ... } 

gibt es eine Möglichkeit in Scala zu bekommen, was ich nach bin? Muss ich eine Klasse definieren und instanziieren?

+0

Der Rückgabetyp von 'set' soll also' {def from (src: String) sein: Unit; Def zu [T] (v: Ausdruck [T]): Einheit} '? –

Antwort

8

Sie einfach ein neues anonymes Objekt zurückgeben kann. Ihre Syntax war fast richtig: ersetzen Sie einfach object von new:

def set(dest: String) = new { 
    def from(src: String) = 
    ... 

    def to[T](v: Expression[T]) = 
    ... 
} 

Dies wird jedoch eine Strukturtyp bei Aufrufort geben, die Reflexion müssen verwenden, um die Methoden zu verwenden. Um dies zu verhindern, ist ein Merkmal mit der API des Objekts definieren:

trait SetResult { 
    def from(src: String): ReturnTypeOfFrom 
    def to[T](v: Expression[T]): ReturnTypeOfTo 
} 

def set(dest: String): SetResult = new SetResult { 
    def from(src: String) = 
    ... 

    def to[T](v: Expression[T]) = 
    ... 
} 

Bitte beachte, dass ich verwenden ReturnTypeOfFrom und ReturnTypeOfSet weil ich keine Ahnung habe, was Ihre Methoden zurück. Übrigens, das ist eine schlechte Angewohnheit: öffentliche Methoden sollten immer einen expliziten Ergebnistyp haben.

+0

Das hat dafür gesorgt. Vielen Dank! –

0

Ich bin mir nicht sicher, was Sie tun möchten, also hoffentlich gibt Ihnen das Startpunkt.
Sie können nicht anonymes Objekt haben, aber Sie innere Objekte haben können, so können Sie tun:

implicit class SessionManagementExtensions(val c: ChainBuilder) { 

    object MyInnerObject { 

    def from(src: String) = 
     c.exec(session => { 
     val list = session(src).as[Vector[String]] 
     val i = if (list.size == 0) -1 else Random.nextInt(list.size) 
     val value = if (i > 0) list(i) else "INVALID_" + dest 
     session.set(dest, value) 
     }) 

    def to[T](v: Expression[T]) = 
     c.exec(session => session.set(dest, v)) 

    } 

    def set(dest: String) = MyInnerObject 

}