Scala: Где я должен размещать заявления импорта?

Scala позволяет импортировать практически все, что угодно, где угодно, и это здорово. Но есть ли какие-либо соображения, которые я должен учитывать при импорте чего-либо внутри класса, метода или всего лишь одного блока? Как это относится к производительности, стилю, поддерживаемости кода и т.д.

В общем, я стараюсь подчиняться этим правилам (составленный мною):

  • Если я импортирую что-то внешнее из другого пакета, я всегда помещаю его вверху сразу после "пакета".
  • Если я использую что-то более одного раза в одном файле, я также импортирую его вверху.
  • В противном случае я помещаю свой импорт вверху соответствующего класса/свойства/объекта.
  • Я не могу импортировать вещи в методы и блоки.
  • Я пытаюсь избежать импорта содержимого объектов экземпляра, если у меня нет повода для этого.
  • Я бы избегал переименования и "скрытия", если только не разрешать конфликты имен, но мне это еще не нужно.

Имеют ли эти "правила" смысл? Я слишком сильно ограничиваю себя?

Ответы

Ответ 1

Как правило, имеет смысл ограничить объем чего-либо (например, переменной или метода) до "наименее", насколько это возможно. Например, используйте внутренний def, а не один на уровне класса. Почему импортные заявления должны быть разными? Зачем загрязнять класс с импортом, который используется только в одном блоке?

Мне нравится объявлять импорт как можно ближе к тому, где они используются!

Таким образом, общие утилиты, такие как scalaz и мои собственные, как правило, импортируются один раз на верхнем уровне (потому что они используются во всем классе). В то время как такие вещи, как I/O, импортируются локально, только там, где они используются

Ответ 2

Нет.

Я не могу импортировать вещи в методы и блоки.

Почему?

Ответ 3

Вы должны помнить, что Scala все еще скомпилирован, и все правила, применимые к Java как язык компиляции, также применимы к Scala. Компилятор должен знать, какой символ вы имеете в виду, когда говорите List или Function.

Вы можете использовать операторы импорта внутри блока, но тщательно их использовать. Излишние могут привести к непоследовательному пониманию исходных файлов другими людьми. Было бы неудобно, если граница одного класса будет использовать два разных определения List, зависящих от контекста.

Ответ 4

правила импорта в Эффективном Scala говорят:

Поместите импорт в верхнюю часть файла

Читатель может обращаться ко всем импортам в одном месте.

В некоторых базовых кодах, с которыми я работал, была тенденция импортировать одно и то же несколько раз в несколько мест в одном файле, потому что разработчик не проверял это. Было бы неплохо, если бы IDE могли автоматически продвигать импорт блоков, если они обнаруживают несколько экземпляров из них, но AFAIK тот, который я использую (IntelliJ), не делает этого.

При работе с большими файлами многие люди обычно смотрят только на свой локальный фрагмент кода, поэтому они могут локально импортировать что-то, что конфликтует с другими частями пакета (например, в одном классе Promise импортируется из scala.concurrent, а в другом - от akka.dispatch), и это сложнее обнаружить, когда у вас есть импорт, посыпанный повсеместно.

Это может быть или не быть релевантным для вашей конкретной базы кода, но я лично склонен пессимистично относиться к коду, который я поддерживаю (энтропия и все такое), и поэтому стараюсь с самого начала вводить правила, которые гарантировали бы поддержку в длинных работать.

Изменить: удалено ссылка на ScalaStyle правило BlockImportChecker, которое не связано.

Ответ 5

Поместите импорт в верхнюю часть файла.

Наличие их разбросанных по всему файлу затрудняет чтение кода:

  • Они не имеют никакого логического смысла, они просто псевдоним; таким образом, они "загрязняют" код, который отражает логический аспект программы.
  • Нельзя ожидать, где их найти (для чего предназначены соглашения).
  • В файлах с несколькими ссылками на объекты с тем же именем, но с другим пространством имен, трудно отслеживать, что это имя ссылается в каждой области.

Я не вижу преимущества в размещении их рядом с их ближайшей областью. Собственно, с учетом этих рассуждений никогда нельзя использовать их вообще; вместо этого всегда следует использовать полное пространство имен для каждого объекта, на который делается ссылка. Имеет ли это смысл? ИМХО, нет.