2015-07-22 11 views
5

Date le seguenti caratteristiche:.Utilizzando v Non uso di `self` Tipo

scala> trait Foo { self => 
    | def f: String = self.getClass.getName 
    | } 
defined trait Foo 

scala> trait Bar { 
    | def f: String = this.getClass.getName 
    | } 
defined trait Bar 

E poi facendo classi che estendono loro:

scala> class FooImpl extends Foo {} 
defined class FooImpl 

scala> class BarImpl extends Bar {} 
defined class BarImpl 

e quindi chiamando i loro f metodi su nuove istanze:

scala> (new FooImpl).f 
res1: String = FooImpl 

scala> (new BarImpl).f 
res4: String = BarImpl 

Il REPL mostra che stampano gli stessi valori - il nome della classe.

Forse questo non è un buon esempio. Ma qual è la differenza tra l'utilizzo di nello Foo sopra rispetto a Bar, che utilizza this?

risposta

5

Nel tuo caso non c'è differenza: stai solo usando un altro nome per this. I tipi di auto sono utili quando è necessario disambiguare tra i diversi this s. Per esempio:

abstract class Foo { self => 
    def bar: Int 
    def qux = new Foo { 
    def bar = self.bar 
    } 
} 

Se abbiamo scritto def bar = this.bar qui, il compilatore si lamentava che la nostra definizione di bar è solo che si fa chiamare in modo ricorsivo, dal momento che la this sarebbe riferendosi alla sottoclasse anonima di Foo stiamo definendo in qux, non l'esterno Foo.

3

Non c'è differenza. self è solo un alias per this. L'unica volta che farà la differenza è se provi a farne riferimento all'interno di una classe interiore o tratto, o oggetto di qualche tipo. ad es .:

trait Foo { self => 
    object InnerFoo { 
     def f: String = self.getClass.getName 
    } 
} 

trait Bar { 
    object InnerBar { 
     def f: String = this.getClass.getName 
    } 
} 

class FooImpl extends Foo 

class BarImpl extends Bar 

scala> (new FooImpl).InnerFoo.f // self still references the outer type Foo 
res4: String = FooImpl 

scala> (new BarImpl).InnerBar.f // this references the inner type InnerBar 
res5: String = Bar$InnerBar$ 
2

Nel caso citato, non c'è praticamente nessuna, come le altre risposte delineate.

Utilizzando un auto-tipo ti dà soprattutto l'occasione per definire ulteriormente il tipo di estensori del tratto, dire che fornisci:

self: Boing =>

Dove

trait Boing { 
    def x 
} 

poi self.x all'interno Foo volontà essere sintatticamente valido, mentre this.x non riuscirà a compilare.

(Si noti, tuttavia, che si può anche perfezionare this allo stesso modo, obliviating la necessità di un identificatore esplicita auto-tipo)

Problemi correlati