Явная типизация в Groovy: иногда или никогда? - PullRequest
19 голосов
/ 14 февраля 2010

[Позже: все еще не могу понять, имеет ли Groovy статическую типизацию (кажется, что нет) или байт-код, сгенерированный с использованием явной типизации, отличается (кажется, что это так). Во всяком случае, к вопросу]

Одним из основных отличий между Groovy и другими динамическими языками - или, по крайней мере, Ruby - является то, что вы можете статически явно вводить переменные, когда хотите.

Тем не менее, когда вы должны использовать статическую типизацию в Groovy? Вот некоторые возможные ответы, которые я могу придумать:

  1. Только при проблемах с производительностью. Статически типизированные переменные быстрее в Groovy. (или это некоторые вопросы по этой ссылке)
  2. В открытых интерфейсах (методах, полях) для классов, поэтому вы получаете автозаполнение. Возможно ли это / правда / совершенно неправильно?
  3. Никогда, он просто загромождает код и побеждает цель использования Groovy.
  4. Да, когда ваши классы будут унаследованы или использованы

Меня интересует не только то, что ВЫ делаете, но, что более важно, то, что вы видели в проектах, написанных на Groovy. Какая норма?

Примечание: Если этот вопрос как-то не так или пропускает некоторые категории статической динамики, дайте мне знать, и я исправлю это.

Ответы [ 4 ]

16 голосов
/ 15 февраля 2010

По моему опыту, нормы нет. Некоторые часто используют типы, некоторые никогда не используют их. Лично я всегда стараюсь использовать типы в сигнатурах моих методов (для параметров и возвращаемых значений). Например, я всегда пишу такой метод

Boolean doLogin(User user) {
// implementation omitted
}

Даже если бы я мог написать это так

def doLogin(user) {
// implementation omitted
}

Я делаю это по следующим причинам:

  1. Документация : другие разработчики (и я) знают, какие типы будут предоставлены и возвращены методом, не читая реализацию
  2. Безопасность типов : хотя в Groovy не выполняется проверка во время компиляции, если я вызову статически типизированную версию doLogin с параметром, отличным от пользователя, это немедленно завершится ошибкой, поэтому проблема, скорее всего, вероятна быть легко исправить Если я вызову динамически типизированную версию, через некоторое время после произойдет сбой , и метод сбоя может быть не сразу очевиден.
  3. Завершение кода : это особенно полезно при использовании хорошей IDE (например, IntelliJ), поскольку она может даже обеспечить завершение для динамически добавляемых методов, таких как динамические искатели класса домена

Я также довольно часто использую типы в реализации моих методов по тем же причинам. Фактически единственные случаи, когда я не использую типы:

  1. Я действительно хочу поддерживать широкий спектр типов. Например, метод, который преобразует строку в число, может также преобразовать коллекцию или массив строк в числа
  2. Лень! Если область действия переменной очень мала, я уже знаю, какие методы я хочу вызвать, и у меня еще нет импортированного класса, тогда объявление типа кажется большим количеством проблем, чем оно того стоит.

Кстати, я бы не стал слишком верить тому посту в блоге, на который вы ссылались, утверждая, что напечатанный Groovy намного быстрее, чем нетипизированный Groovy. Я никогда не слышал этого раньше, и я не нашел доказательства очень убедительными.

2 голосов
/ 10 марта 2010

Я работал над несколькими проектами Groovy, и мы придерживались таких соглашений:

  • Все типы в открытых методах должны быть указаны.

    public int getAgeOfUser (String userName) { ... }

  • Все приватные переменные объявляются с использованием ключевого слова def .

Эти соглашения позволяют вам достичь многих вещей.

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

С другой стороны, область действия метода обычно довольно мала, поэтому вам не нужно явно объявлять типы. Кстати, современные IDE могут автоматически заполнять ваши локальные переменные, даже если вы используете defs.

1 голос
/ 14 февраля 2010

Я видел информацию о типах, используемую в основном в классах обслуживания для открытых методов. В зависимости от сложности списка параметров, даже здесь я обычно вижу только тип возвращаемого значения. Например:

class WorkflowService {
    ....
    WorkItem getWorkItem(processNbr) throws WorkflowException {
        ...
        ...
    }
}

Я думаю, что это полезно, потому что оно явно сообщает пользователю сервиса, с каким типом он будет иметь дело, и действительно помогает с кодом в IDE.

0 голосов
/ 14 февраля 2010

Groovy не поддерживает статическую типизацию. Убедитесь сами:

public Foo func(Bar bar) {
  return bar
}
println("no static typing")

Сохраните и скомпилируйте этот файл и запустите его.

...