Как на самом деле работает связывание переменных в groovysh?

Вот суть того, чего я не понимаю:

% groovysh
Groovy Shell (1.8.6, JVM: 1.6.0_21)
Type 'help' or '\h' for help.
------------------------------------------------------
groovy:000> class vars {
groovy:001> static int x = 1;
groovy:002> }
===> true
groovy:000> println new vars().x
1
===> null
groovy:000> println vars.x
ERROR groovy.lang.MissingPropertyException:
No such property: vars for class: groovysh_evaluate
Possible solutions: class
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

Если vars разрешается во что-то в выражении new vars().x, то почему не разрешается и в выражении vars.x? Это похоже на фантомный идентификатор, который на самом деле существует только для целей инстанцирования.


person Maxy-B    schedule 08.05.2013    source источник


Ответы (2)


Ваш код не работает, потому что вы используете неправильные соглашения об именах. Вы должны написать класс с заглавной буквы V. Таким образом, оболочка Groovy узнает, что вы имеете в виду класс, а не переменную, на случай, если Groovy не сможет ее определить.

Это то, что вы действительно хотите:

groovy:000> class Vars {
groovy:001>     static int x = 1
groovy:002> }
===> true
groovy:000> Vars.x
===> 1

Надеюсь, это поможет!

person Erik Pragt    schedule 08.05.2013
comment
Ух ты! Звучит как эпический хак/эвристика в реализации groovysh. Интересно, что new vars() работает просто отлично. - person Maxy-B; 09.05.2013
comment
Продолжение: есть ли где-нибудь документация по всем правилам, подобным этому, которые groovysh использует для разрешения имен в классы/переменные/и т. д.? - person Maxy-B; 09.05.2013
comment
Конечно, «новые вары» прекрасно работают, см. мое объяснение ниже. Между прочим, сработает «myVars = new vars()». Это создает переменную. - person Erik Pragt; 09.05.2013

Ваша проблема в том, что vars — это класс, а не объект, а x не объявлен как статическое свойство. Лучше всего всегда называть свои классы заглавными буквами, чтобы избежать такой путаницы.

person Big Ed    schedule 08.05.2013
comment
Лол, на самом деле x статичен. И случай не имеет отношения к вопросу. - person Maxy-B; 08.05.2013
comment
Я не уверен, почему за этот ответ проголосовали отрицательно, поскольку это (в основном) правильный ответ, за исключением статической части. Переменная vars, о которой вы говорите, не существует. Нет переменной с именем vars, только класс, поэтому сообщение об ошибке: «нет такого свойства» - person Erik Pragt; 09.05.2013
comment
Спасибо. Однако я действительно неправильно понял вопрос, и меня должным образом наказали. - person Big Ed; 09.05.2013
comment
Извините, @BigEd, это действительно был нижний регистр, хотя ваш ответ звучал так, как будто это был вопрос стиля, а не фактического синтаксиса groovysh. Я отменю свой отрицательный голос, как только замок снимется. - person Maxy-B; 09.05.2013
comment
@ErikPragt, я не уверен, что это правда, что нет переменной vars; ведь new vars() работает. Вместо этого я бы сказал, что vars — это переменная (т. е. имя), которая именует (т. е. связана, разрешается, ссылается) на класс. По крайней мере, я этого и ожидал; но очевидно, что groovysh зависит от определенных соглашений об именах с учетом регистра, чтобы помочь ему понять, к чему именно относится данное имя, что я здесь нарушал. - person Maxy-B; 09.05.2013
comment
Привет Maxy-B, я уверен, что переменных vars нет. 'new vars()' создает не переменную, а новый объект. Вы можете быть сбиты с толку, потому что перепутали верхний и нижний регистры). Неправильно говорить, что «vars» — это переменная. Кстати, это не имеет ничего общего с groovysh, также без groovysh «новые переменные» все равно не были бы переменной. - person Erik Pragt; 09.05.2013
comment
Возможно, я был немного небрежен с термином переменная. Я имею в виду имя, токен, последовательность символов в языке программирования, которая может на что-то ссылаться. Код class vars {...} создает имя vars в некотором пространстве имен, которое относится к классу; вы используете это имя при создании экземпляра класса с помощью new vars(); Что сбивает с толку в Groovy, так это то, что он терпит неудачу, когда вы пытаетесь использовать то же имя для ссылки на его статический член. - person Maxy-B; 09.05.2013
comment
Поскольку все в Groovy является объектом, vars будет объектом, являющимся экземпляром java.lang.Class. - person Big Ed; 16.05.2013