Могут ли некоторые проиллюстрировать концепцию языка, такого как Java или Groovy, который рассматривается как статически или динамически типизированный или динамический язык?

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

Что меня смущает, так это то, что если известно, что язык статически типизирован, когда тип переменной известен или определен во время компиляции в случае Java, т.е.

//Java illustration of statically typed  
int x, y; //explicit type declaration 
x = 5, y = 10; //Now we use the variables 

//Groovy illustration of statically typed 
def x, y //explicit type declaration 
x = 1, y = 10 //now we use the variables

На основании чтения различных онлайн-источников говорится, что список языков, которые считаются статически типизированными, не включает Groovy, но включает Java и C ++.

Также, если Groovy является динамическим языком (определение DL - DL - это язык, который мало проверяет или не выполняет никаких проверок во время компиляции, вместо этого проверки выполняются во время выполнения). Разве это не означает, что Groovy также является языком с динамической типизацией, потому что переменная считается динамически типизированной «тогда, когда тип переменной известен во время выполнения, а не во время компиляции».

//Illustration of a language being dynamically typed according to DT and DL definition
x = 5 //directly using the variable (exceptable in Python and PHP but not in Java/Groovy)

Если это так в Groovy, то приведенная выше иллюстрация кода статической типизации Groovy противоречит определению Groovy проверок, выполняемых во время выполнения.

Означает ли это, что оба java groovy не являются динамически типизированными языками, потому что прямое использование переменной вызовет ошибку компилятора как в Java, так и в groovy.

Пожалуйста, поправьте меня, если ошибаюсь. Пожалуйста, предоставьте свои примеры с иллюстрацией кода.


person Learner    schedule 24.01.2013    source источник
comment
Как объявить def x; x = 1 статически типизированным? Информация о типе не предоставляется.   -  person Dave Newton    schedule 25.01.2013
comment
@DaveNewton - def - ключевое слово определения, которое означает, что этот тип переменной может быть любым (Object, String, int и т. Д.) Во время выполнения, но в конце дня это тип по умолчанию. Среда выполнения будет интерпретировать тип переменной на основе значения переменной, если переменной задан тип def.   -  person Learner    schedule 25.01.2013
comment
@Learner, а разница между динамической типизацией и тем, что вы только что сказали ...?   -  person tim_yates    schedule 25.01.2013
comment
@Learner Я не совсем уверен, что вы только что сказали - я спрашиваю, почему это не динамическая типизация, поскольку тип, поддерживаемый x, может измениться.   -  person Dave Newton    schedule 25.01.2013
comment
@DaveNewton - я имел в виду, что def по умолчанию - это тип, не так ли? Если переменной присваивается тип def и ей присваивается любое значение. Затем его тип будет интерпретирован во время выполнения. Правильный?   -  person Learner    schedule 25.01.2013
comment
@Learner Ааааи это динамическая типизация. Но нет, def не тип. Это любой тип. Что-либо. Если тип значения может измениться, то он динамический.   -  person Dave Newton    schedule 25.01.2013
comment
@DaveNewton - Итак, Groovy также является статически типизированным или статически или динамически типизированным?   -  person Learner    schedule 25.01.2013
comment
@Learner Это динамически типизированный. Groovy 2+ добавляет необязательную проверку статического типа, так что это и то, и другое, но пример, который вы называете статически типизированным, - нет. Необходимость def для устранения неоднозначности в объявлениях переменных не делает их статически типизированными.   -  person Dave Newton    schedule 25.01.2013
comment
def - это не более тип, чем for. 'def' - это ключевое слово для обозначения имени после того, как это новая переменная, точно так же, как 'for' - это ключевое слово, указывающее, что за некоторыми параметрами цикла следует оператор (или их блок), следующий за ним.   -  person Lee Meador    schedule 25.01.2013
comment
Фактически def можно заменить на Object. В Java вы можете хранить все в объекте, но значение, содержащееся в этом объекте, всегда имеет известный тип во время выполнения. Переменная типа Object всегда считается (по крайней мере) объектом во время компиляции и, возможно, чем-то более конкретным. Это справедливо как для Java, так и для Groovy, но Groovy имеет тенденцию работать с объектами чаще, чем с Java. Groovy также позволяет вам попытаться вызвать метод объекта, которого он может не иметь, а Java - нет. Это главное отличие.   -  person Bill K    schedule 26.01.2013
comment
Также def i = 7 так же полностью типизирован, как и в java - часть i = 7 создает I как int / Integer так же точно, как если бы вы набрали int i = 7 и вставили его в и Object. Это просто синтаксический ярлык, а не отсутствие текста   -  person Bill K    schedule 26.01.2013
comment
@Learner, в отличном скрипте def не является обязательным префиксом. вы можете использовать x=5, и он будет работать.   -  person daggett    schedule 23.06.2021


Ответы (3)


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

На языке с динамической типизацией переменная - это просто имя. Вы можете присвоить значения любого типа любой переменной, и тип можно изменить, присвоив значение другого типа. Допустимость вызова функции или операции с переменной можно проверить только во время выполнения оператора. (Вы можете думать об этом как об объявлении каждой переменной в Java как об объекте и приведении их к желаемому типу при использовании. Конечно, компилятор не будет пытаться определить, будет ли приведение успешным, и будет вставлять проверки приведения, которые могут вызвать сбой при запуске время.)

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

person billc.cn    schedule 24.01.2013

Я поставил это как комментарий, но он был немного похоронен.

def ДЕЙСТВИТЕЛЬНО дает тип, он использует тип "Object". Это как если бы каждая переменная, определенная в Java, была определена как объект ... (так что def x = 7 в Groovy в точности совпадает с Object x = 7 в Java, не более или менее типизированным).

Эти объекты ВСЕГДА хранят информацию о своем типе на обоих языках. Эти два также эквивалентны:

Groovy:
def x=5
assert(x == 5)
x="Hey, I changed type!"
assert(x == "Hey, I changed type!")

Java:
Object x=5
assert(x == 5);
x="Hey, I--well I kinda changed my type!"
assert(x.equals("Hey, I--well I kinda changed my type!"))

Большая разница в том, что Java требует (во время компиляции), что вы вызываете ТОЛЬКО известные методы для того типа класса, который, по ее мнению, у вас есть ... поэтому в приведенном выше примере .toString () и .equals () действительно являются единственными полезными методами. . Чтобы заниматься математикой, вам нужно сделать что-то вроде этого:

Object x=5;
Object y=7;
Object z=(int)x + (int) y;
assert(z == 12);  
// I believe Integer z will automatically turn 
// to an int here, but this might not compile :)

В Groovy язык все равно будет пытаться вызвать метод, и во время выполнения будет либо успешно, либо неуспешно.

Это можно эмулировать с помощью Java с помощью отражения, вы можете набрать все как «Object» (как в случае с Groovy «def») и написать отражающую утилиту, которая будет делать что-то вроде этого:

Object s="Hey, Wassup???";
Object s2=magic(s, "toLowerCase")
assert(s2.equals("hey, wassup???"));

Groovy просто скрывает «волшебство».

Поэтому я не думаю, что вы могли бы сказать, что один по своей сути более динамичен, чем другой, хотя вы, вероятно, могли бы сказать, что использование отражения делает оба языка динамическими, и вы также можете сказать, что Groovy использует отражение НАМНОГО больше, чем java ...

person Bill K    schedule 25.01.2013

Обратите внимание, что в Java вам нужно было указать полный тип переменной. 'int' в вашем примере. Вы могли бы сказать «float», «Map» или «MyClassWithALongName».

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

person Lee Meador    schedule 24.01.2013
comment
Это не ответ на вопрос. Я знаю, что это могут быть разные типы, о которых вы упомянули, но это не мой вопрос. - person Learner; 25.01.2013
comment
@Learner Тогда вам нужно прояснить свой вопрос: вы говорите, что что-то явно не статическая типизация - это статическая типизация. - person Dave Newton; 25.01.2013
comment
Это не ответ на вопрос. Я знаю, что это могут быть разные типы, о которых вы упомянули, но это не мой вопрос. Вопрос в том, что если программисты вынуждены явно объявлять тип переменной в Groovy (то есть по умолчанию def type или String и т. Д.), Groovy также следует рассматривать как язык со статической типизацией. Потому что нельзя объявить переменную безтиповой x = 5; //directly using variable. Объявление переменных без типа возможно только в PHP! - person Learner; 25.01.2013
comment
@ Ученик ... def не объявляет тип. Процитируем: def - это замена имени типа. В определениях переменных он используется, чтобы указать, что вас не волнует тип. def - это, по сути, псевдоним для Object. Другими словами, ЛЮБОЙ ТИП. Это динамическая типизация. - person Dave Newton; 25.01.2013
comment
@DaveNewton - Правильно, если def является псевдонимом для Object, то не означает ли это, что Object является отдельным типом? - person Learner; 25.01.2013
comment
@ Ученик ... Я не понимаю, почему это сложно. В Java, если у вас есть Object ссылка, вы можете вызывать Object методы для нее. В Groovy, если у вас есть def x, вы можете отправлять ему любое сообщение, и если объект может ответить на него, он это сделает. Это определение динамической типизации. Не знаю, как еще это объяснить. Удачи! - person Dave Newton; 25.01.2013
comment
@DaveNewton - Я думаю, вы путаете себя с динамическим языком? динамический тип и динамический язык - две разные концепции. - person Learner; 25.01.2013
comment
@ Ученик, я уверен, что нет. - person Dave Newton; 25.01.2013
comment
@Learner Другими словами, в Java тип переменной статический. Статичность означает, что она неизменна. Тип переменной указывает, какие типы значений данных она может содержать. Переменная Java может содержать только один тип данных. В Groovy переменная имеет динамический тип. Динамический означает, что он изменчив. Это не изменится, если вы что-то не сделаете, но сами данные имеют тип, а переменная просто хранит его, независимо от типа. (Я ничего не говорю о том, являются ли они динамическими языками. Я говорю только о том, что они печатают.) - person Lee Meador; 25.01.2013