Подтвердить что ты не робот

Явная типизация в Groovy: иногда или никогда?

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

def doLogin(user) {
// implementation omitted
}

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

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

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

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

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

Ответ 2

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

  • Необходимо указать все типы в общедоступных методах.

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

Groovy не поддерживает статическое типирование. Посмотрите сами:

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

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