Начиная с 2.10, -Xlint
жалуется на классы, определенные внутри объектов пакета. Но почему? Определение класса внутри объекта пакета должно быть в точности эквивалентным определению классов внутри отдельного пакета с тем же именем, кроме гораздо более удобного.
По моему мнению, одним из серьезных недостатков дизайна в Scala является невозможность помещать на верхнем уровне файла ничего, кроме класса (например, объявления переменных, определения функций). Вместо этого вы вынуждены помещать их в отдельный "объект пакета" (часто в package.scala
), отдельно от остальной части кода, к которому они принадлежат, и нарушая основное правило программирования, которое является тем, что концептуально связанный код должен быть физически связанными также. Я не вижу причин, почему Scala не может концептуально разрешить что-либо на верхнем уровне, которое он допускает на более низких уровнях, и что-то неклассическое автоматически помещается в объект пакета, так что пользователям никогда не придется беспокоиться о он.
Например, в моем случае у меня есть пакет util
, и под ним у меня есть несколько подпакетов (util.io
, util.text
, util.time
, util.os
, util.math
, util.distances
и т.д.), которые группируют гетерогенные коллекции функций, классов и иногда переменных, которые семантически связаны между собой. В настоящее время я храню все различные функции, классы и т.д. В package object
, сидящем в файле с именем io.scala
или text.scala
или любым другим, в каталоге util
. Это отлично работает, и это очень удобно из-за того, что функции и классы могут быть смешаны, например. Я могу сделать что-то вроде:
package object math {
// Coordinates on a sphere
case class SphereCoord(lat: Double, long: Double) { ... }
// great-circle distance between two points
def spheredist(a: SphereCoord, b: SphereCoord) = ...
// Area of rectangle running along latitude/longitude lines
def rectArea(topleft: SphereCoord, botright: SphereCoord) = ...
// ...
// ...
// Exact-decimal functions
class DecimalInexactError extends Exception
// Format floating point value in decimal, error if can't do exactly
formatDecimalExactly(val num: Double) = ...
// ...
// ...
}
Без этого мне пришлось бы разбить код неудобно в соответствии с потехой и классом, а не с семантикой. Альтернатива, я полагаю, заключается в том, чтобы поместить их в нормальный объект - вид победить цель иметь объекты пакета в первую очередь.