Reputation: 41909
Given the following traits:
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
And then making classes that extend them:
scala> class FooImpl extends Foo {}
defined class FooImpl
scala> class BarImpl extends Bar {}
defined class BarImpl
And then calling their f
methods on new instances:
scala> (new FooImpl).f
res1: String = FooImpl
scala> (new BarImpl).f
res4: String = BarImpl
The REPL shows that they print out the same values - the class's name.
Perhaps this isn't a good example. But what's the difference of using self
in the above Foo
compared to Bar
, which uses this
?
Upvotes: 5
Views: 105
Reputation: 9705
In the quoted case, there's basically none, as the other answers outlined.
Using a self-type mainly gives you an opportunity to further define the type of your trait's extenders, say you provide:
self: Boing =>
Where
trait Boing {
def x
}
then self.x
within Foo
will be syntactically valid, whereas this.x
will fail to compile.
(Note, however, that you can also refine this
the same way, obliviating the need for an explicit self-type identifier)
Upvotes: 2
Reputation: 55569
There is no difference. self
is just an alias for this
. The only time it will make a difference is if you try to reference them within an inner class or trait, or object of some kind. e.g.:
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$
Upvotes: 3
Reputation: 139038
In your case there's no difference—you're just using another name for this
. Self types are useful when you need to disambiguate between different this
s. For example:
abstract class Foo { self =>
def bar: Int
def qux = new Foo {
def bar = self.bar
}
}
If we wrote def bar = this.bar
here, the compiler would complain that our definition of bar
is just calling itself recursively, since the this
would be referring to the anonymous subclass of Foo
we're defining in qux
, not the outside Foo
.
Upvotes: 5