Groovy смешанного набора текста
Я вижу, что в Groovy 2.0 есть возможность добавить TypeChecked
аннотация к классам или методам для запуска необязательной статической проверки.
Я должен признать, что я смущен тем, как такая вещь может работать. В статье приводятся простые примеры, такие как
@TypeChecked
Date test() {
// compilation error:
// cannot assign value of Date
// to variable of type int
int object = new Date()
String[] letters = ['a', 'b', 'c']
// compilation error:
// cannot assign value of type String
// to variable of type Date
Date aDateVariable = letters[0]
// compilation error:
// cannot return value of type String
// on method returning type Date
return "today"
}
В этом случае ясно, что некоторые проверки не пройдут. Но в общем случае можно использовать, скажем, возвращаемое значение метода A
, то есть не проверяется тип, внутри метода проверенного типа B
, В этом случае я не вижу, как компилятор может выяснить, является ли метод B
типы согласованы, так как у него недостаточно информации о возвращаемом значении метода A
,
Как можно включить проверку типов в подмножестве кода, не теряя при этом безопасность типов в целом?
РЕДАКТИРОВАТЬ
Я пытаюсь сделать пример. Что делать, если у меня есть старый класс
class Old {
public getFoo() {
return 1
}
}
и попробуйте использовать его из проверенного типа кода, как
@TypeChecked
class New {
int doubleFoo() {
return 2 * (new Old().foo)
}
}
Компилятор просто не знает, что делать, и я думаю, что он не скомпилируется (у меня на работе не установлен Groovy2 для проверки). Но если это так, то становится проблемой использовать любой код, написанный до Groovy2. Так что я представляю, что что-то более сложное сделано, но я не уверен, что.
1 ответ
Там нет такой проблемы. Если вы вызываете метод из непроверенного класса, тогда используется объявленный тип возвращаемого значения, и поведение точно такое же, как если бы вы использовали метод Java из Groovy.
Возьмите следующий пример:
class A {
int foo() { 1 }
}
@TypeChecked
class B {
void bar() {
int x = new A().foo() // uses the type from A.foo, correct
}
}
Теперь представьте это:
class A {
Date foo() { new Date() }
}
@TypeChecked
class B {
void bar() {
int x = new A().foo() // uses the type from A.foo, foo returns a Date, the compiler throws an error
}
}
Обратите внимание, что в общем случае вы используете смешанную проверку типов в одном классе, если у вас есть код, который сильно зависит от динамического кода, который средство проверки типов, очевидно, не может проверить. Это имеет место, например, если вы полагаетесь на строителя. Если это так, тогда вы просто объявляете метод, который использует конструктор, как не проверенный, а остальная часть вашего кода проверяется. Пока метод unchecked возвращает совместимый тип, безопасность типов гарантируется.