Здесь возникает проблема (неявная) оператор распространения в Groovy.
Выражение cars*.make
эквивалентно cars.collect{ it.make }
.Нотация GPath Groovy позволяет использовать ярлык, когда указанное свойство не является свойством содержащего списка, в этом случае оно автоматически распространяется.В ранее упомянутом случае можно использовать выражение cars.make
, хотя часто рекомендуется сохранять явный оператор растягивания.
(пример там говорит о GPath, но то же самое верно длясписки, карты, ...)
Так что lock1.unlock()
в данном случае lock1*.unlock()
.(Динамически) Groovy увидит, что в списке нет метода unlock()
, а просто распущен.
Что касается "Таким образом, наиболее вероятно, lock1 является объектом для блокировки класса" Даст вам кошмары.Не угадай - узнай.Вы можете println(lock1.inspect())
для деталей, и мы надеемся, что автор этого класса был предвидением, чтобы добавить полезный метод toString()
.Проверьте документы, что функция возвращает, вы назначаете locks1
от.Используйте инструментальные средства, которые сообщают вам тип (IDE, отладчик, ...).
Для разработчиков лучше помогает именование:
// BAD naming
def locks1 = smartThings.getAll(Lock, clientId)
// better naming, add the type if it helps you or your IDE
Collection<Lock> allLocks = smartThings.getAll(Lock, clientId)
Теперь, если вы позвоните allLocks.lock()
, этоБолее очевидно, что происходит.
Чтобы предотвратить неявный оператор распространения, вы можете использовать статическую компиляцию в вашем скрипте groovy.Например:
class Lock {
def lock() { println "lock" }
def unlock() { println "unlock" }
}
@groovy.transform.CompileStatic
class X {
public static main() {
[new Lock()].lock()
}
}
Это не скомпилируется:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
x.groovy: 9: [Static type checking] - Cannot find matching method java.util.List#lock(). Please check if the declared type is correct and if the method exists.
@ line 9, column 3.
[new Lock()].lock()
^
1 error
При использовании явного оператора распространения ([new Lock()]*.lock()
) компилируется.