2016-09-15 3 views
5

Вопросы по иерархии классов в Scala:иерархии классов в Scala

  1. В IntelliJ IDE, я ищу для реализации Any и AnyRef, но их там нет. Где они определены и как я могу увидеть их код?

  2. Я прочитал следующее в «Программирование в Scala»

Единственный случай, когда == не вызывать напрямую равно для штучной числовых классов Java, таких как Integer или Long. В Java новый Integer (1) не равен новому длинному (1), хотя для примитивов значения 1 == 1L. Поскольку Scala является более регулярным языком, чем Java, для устранения этого несоответствия необходимо было установить с помощью специального метода == для этих классов.

Хм ... но не == окончательный? Как они сделали особый случай для числовых классов Java?

+0

http://stackoverflow.com/questions/13010984/where-can-i-find-the-definition-of-scala-any-and-scala-anyref Может быть полезно для первого вопроса –

ответ

7

Any, AnyRef, Null и Nothing на самом деле не существует; они включены, чтобы система типов была полной, но они не имеют реального представления. Вы можете найти a reference in Scala's repository, но, как говорится, они фактически не компилируются и не существуют только для документации и загрузки. Scala's 3 Any* s на самом деле все java.lang.Object в скомпилированном байт-коде.

Кроме того, классы примитивных значений (Int, Long и т. Д.) Определены final abstract, что означает, что они также фактически не существуют. Все их методы абстрактны.

Для того, чтобы все выглядело аккуратно и аккуратно, а главное, работа, это работа компилятора, чтобы подделать существование этих типов и выполнить магию, чтобы все это склеивалось. Это то, что позволяет == делать нулевые проверки и правильно обрабатывать типы значений, хотя это final, поскольку компилятор делает магию вокруг него. В случае new java.lang.Integer(5) == new java.lang.Long(5), оно сводится к scala.runtime.BoxesRuntime.equalsNumNum(new java.lang.Integer(5), new java.lang.Long(5)).

+0

Это очень много магия, была ли причина, почему бы не сделать ее более простой? Кроме того, вы говорите, что компилятор действительно нарушает окончательное правило, не проблема (для тех, кто смотрит на код ссылки, хотя он не компилируется)? – rapt

+0

@rapt В моих глазах это * довольно просто. В Scala-land у нас есть звуковая система * normal * type с нижним типом 'Nothing', верхним типом' Any', примитивами (почти) нормальными подклассами 'AnyVal', примитивными операциями типа' + 'и'/'как нормальные абстрактные методы на примитивных классах и т. д. Магия случается, когда эту систему нужно сжимать на JVM и ее ограничения. – HTNW

+0

Я не спрашиваю о дизайне идеальной системы, но о реализации. Была ли какая-либо проблема для реализации реальных Any, AnyRef, а также конкретных Int, бетона Long и т. Д.? – rapt

6

Это нормально для языков, где есть «магические» части, подобные этому. Части, которые не могут быть описаны в самом языке.

Очевидный пример: вы можете объявить суперкласс или вы не можете объявить суперкласс, и в этом случае суперкласс будет AnyRef. Итак, как вы пишете Any, класс, который не имеет суперкласса? Ну, ты не можешь. Вы можете расширить язык и позволить программистам писать классы без суперклассов, но тогда вы больше не можете гарантировать, что Any является только таким классом, и поэтому ваша иерархия наследования больше не будет представлять собой решетку. Но правила проверки типов и типов ввода зависят от от иерархии наследования, являющейся решеткой.

Таким образом, единственным разумным выбором является определение Any, которое фактически не может быть выражено в самом языке.

Это не свойственно Scala: у вас такая же проблема с Java и Ruby's Object, например.

На самом деле, Scala имеет много меньше таких «магия» по сравнению с другими языками господствующих ... и значительная часть «магии», это действительно есть для совместимости с платформой основной принимающей экосистемы (Java для Scala -JVM, ECMAScript для Scala.js, CLI для заброшенной Scala.NET, CoreFoundation для гипотетического Scala-macOS и т. Д.).

+0

Извините, я не понимаю вашу формулировку. Суперкласс имеет как минимум два значения: родительский класс и конечный родительский класс (например, Object в Java) - что вы имели в виду? Кроме того, что не так, когда 'Any' является подклассом java.lang.Object, и если вы меня правильно понимаете, вы обеспокоены тем, что' Any' будет по-прежнему иметь родителя, то почему бы не отключить его через компилятор. Во всяком случае, по-прежнему можно получить доступ к «Object» из Scala, поэтому «Any» на самом деле не является окончательным суперклассом. – rapt

+1

@rapt 'Any' на самом деле является высшим суперклассом. Система типов разработана таким образом, что 'Any' находится над' Object'. Вы можете доказать это, выполнив 'implicitly [Object <: HTNW

+0

Вы правы, я пренебрег этим фактом. Поэтому Any & AnyRef не может компилироваться в соответствии со своим ссылочным кодом. Любая идея, какова была бы причина не-конкретных классов значений (Int, Long и т. Д.)? – rapt

Смежные вопросы