The Types Scaladoc page warns:
Type Equality can be checked with =:=. It's important to note that == should not be used to compare types for equality-- == can't check for type equality in the presence of type aliases, while =:= can.
There is no similar warning for Symbols, but looking at the implementation, it doesn't appear to override equals
. Is there a way to compare symbols for equality (i.e. whether they represent the same Scala type/val/method/etc.)?
For TypeSymbol
s I can obviously use .toType
and =:=
, so the question is primarily about TermSymbol
s.
It seems as though ==
is fine for symbols (to an extent). I don't want to try to over-interpret the scaladoc, but I don't think aliases matter with them. (I would also hope that the section on symbols would contain a similar warning.)
Symbols are used to establish bindings between a name and the entity it refers to, such as a class or a method. Anything you define and can give a name to in Scala has an associated symbol.
versus Type
:
As its name suggests, instances of Type represent information about the type of a corresponding symbol. This includes its members (methods, fields, type aliases, abstract types, nested classes, traits, etc.) either declared directly or inherited, its base types, its erasure and so on. Types also provide operations to test for type conformance or equivalence.
The documentation suggests that Type
s contain more valuable information than Symbol
s.
Example:
type L[A] = List[A]
scala> typeOf[L[String]].typeSymbol == typeOf[List[String]].typeSymbol
res47: Boolean = true
The Symbol
s are equal, even though the Type
s are not. So while L[A]
and List[A]
have different Type
s from the alias, they both resolve to the same Symbol
. The inner-type information appears to be gone though, and the Symbol
appears to contain the information on the List
class itself.
scala> typeOf[List[String]].typeSymbol
res51: reflect.runtime.universe.Symbol = class List
scala> typeOf[L[String]].typeSymbol
res52: reflect.runtime.universe.Symbol = class List
So these are equal:
scala> typeOf[L[String]].typeSymbol == typeOf[L[Int]].typeSymbol
res55: Boolean = true
While these are not:
scala> typeOf[L[String]] =:= typeOf[L[Int]]
res56: Boolean = false
So while it appears while the underlying types should have the same Symbol
, the Symbol
might not contain all the information you need for the full comparison illustrated above.