From 3543e906b188e8d15aaa6dfdb17ba8e5ec3618f2 Mon Sep 17 00:00:00 2001 From: Nikolay Gagarinov Date: Wed, 24 Jun 2026 01:31:38 +0500 Subject: [PATCH] =?UTF-8?q?feat(33-data-types):=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=20=D1=82=D0=B5=D0=BE=D1=80=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=B8=D0=B7=20Python=20=D0=B8=20=D0=B0=D0=B4=D0=B0=D0=BF=D1=82?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=B4=20java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Расширены три урока модуля «Типы данных» до объема Python-эталона и адаптированы под Java: - 41-data-types-basics (зачем нужны типы): примитивы int/double/ boolean/char и ссылочный String, char в одинарных кавычках против строки в двойных - 45-explicit-types (явная типизация): статическая типизация, тип фиксируется при объявлении, проверка на стадии компиляции, var и вывод типов - 55-type-casting (приведение типов): Integer.parseInt, приведение (int)/(double), целочисленное деление и (double) 7 / 2 Перенесены definitions/tips из Python ru/data.yml с сохранением Java-имен уроков. Код уроков, es/en, EXERCISE.md не тронуты. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../41-data-types-basics/ru/README.md | 38 ++++++++----- .../41-data-types-basics/ru/data.yml | 14 +++++ .../45-explicit-types/ru/README.md | 55 +++++++++++++++++-- .../45-explicit-types/ru/data.yml | 11 ++++ .../55-type-casting/ru/README.md | 33 ++++++++--- .../33-data-types/55-type-casting/ru/data.yml | 8 +++ 6 files changed, 134 insertions(+), 25 deletions(-) diff --git a/modules/33-data-types/41-data-types-basics/ru/README.md b/modules/33-data-types/41-data-types-basics/ru/README.md index a897e2a..fa840cb 100644 --- a/modules/33-data-types/41-data-types-basics/ru/README.md +++ b/modules/33-data-types/41-data-types-basics/ru/README.md @@ -1,11 +1,11 @@ -Внутри высокоуровневых языков программирования данные разделяются по типам. Например, строки относятся к типу *String*, а числа — к типу *int*. +Программы работают с разной информацией. Это текст, числа, даты, логические значения. Внутри высокоуровневых языков программирования каждое значение относится к какому-то типу. Например, строки относятся к типу *String*, а целые числа — к типу *int*. -Зачем нужны типы? Для защиты программы от трудноотловимых ошибок. Типы определяют две вещи: +Зачем нужны типы? Они защищают программу от трудноотловимых ошибок. Тип определяет две вещи. -* Допустимые значения. Например, числа в Java делятся на две группы типов: целые *int* и рациональные *float*. Такое разделение связано с техническими особенностями работы аппаратуры. -* Набор допустимых операций. Например, операция умножения имеет смысл для типа «целые числа». Но не имеет смысла для типа «строки»: умножать слово «мама» на слово «блокнот» — бессмыслица. +* Допустимые значения. Например, числа в Java делятся на две группы. Целые числа относятся к типу *int*, а рациональные (дробные) — к типу *double*. Такое разделение связано с особенностями работы аппаратуры. +* Набор допустимых операций. Например, операция умножения имеет смысл для целых чисел. Но не имеет смысла для строк. Умножать слово "мама" на слово "блокнот" — бессмыслица. -Язык программирования распознает типы. Поэтому Java не позволит нам умножать строку на строку. Но позволит умножать целое число на другое целое число. Наличие типов и таких ограничений в языке защищает программы от случайных ошибок: +Язык программирования распознает типы. Поэтому Java не позволит умножать строку на строку, но позволит умножать целое число на другое целое число. Наличие типов и таких ограничений защищает программы от случайных ошибок: ```text "one" * "two" @@ -15,18 +15,30 @@ bad operand types for binary operator '*' second type: java.lang.String ``` -Каким образом Java понимает, что за тип данных перед ним? Любое значение где-то инициализируется. В зависимости от способа инициализации, становится понятно, что именно находится перед нами. +## Числа и строки относятся к разным типам -Например, число — это просто число, не обернутое в кавычки или другие парные символы. А вот строки всегда ограничены двойными кавычками. Например, значение `"234"`считается строкой, хотя внутри нее записаны цифры: +Каким образом Java понимает, что за тип данных перед ней? По способу записи значения. Число записывается без кавычек, а строки всегда ограничены двойными кавычками. Например, значение `"234"` считается строкой, хотя внутри записаны цифры: ```java -// Компилятор понимает что тут число -var age = 33; +System.out.println(5); // => 5 +System.out.println("234"); // => 234 ``` -По-английски строки в программировании называются *strings*, а строчки текстовых файлов называются *lines*. Например, в коде выше одна строчка (*lines*) и ноль строк (*strings*). В русском языке иногда может быть путаница, поэтому во всех уроках мы будем использовать такие термины: +На экране результат выглядит похоже, но внутри программы это разные значения. Число `5` относится к типу *int*, а `"234"` — к типу *String*. Сложить строку и число напрямую Java не даст без явного указания, как преобразовать данные. -* **Строка** — для обозначения типа данных *strings* -* **Строчка** — для обозначения *lines* (строчек в текстовых файлах) +## Примитивные и ссылочные типы -Типов данных в Java много, плюс можно создавать свои. Постепенно мы познакомимся со всеми необходимыми и научимся их правильно использовать. +Часть типов встроена в язык. Их называют примитивными. Кроме целых чисел *int* и рациональных *double*, к ним относятся логический тип *boolean* со значениями `true` и `false`, а также символ *char*: + +```java +int n = 5; // целое число +double x = 1.5; // рациональное число +boolean flag = true; // логическое значение +char c = 'A'; // один символ +``` + +Обратите внимание на тип *char*. Символ записывается в одинарных кавычках, например `'A'`. А вот строка из одного символа заключается в двойные кавычки, например `"A"`. Это разные значения разных типов. + +Тип *String* относится к ссылочным типам и описывает набор символов, то есть текст. При этом строки используются наравне с примитивными типами. + +Типов данных в Java много, плюс можно создавать свои. Постепенно мы познакомимся со всеми необходимыми и научимся правильно их использовать. diff --git a/modules/33-data-types/41-data-types-basics/ru/data.yml b/modules/33-data-types/41-data-types-basics/ru/data.yml index a17ccbb..494f4a4 100644 --- a/modules/33-data-types/41-data-types-basics/ru/data.yml +++ b/modules/33-data-types/41-data-types-basics/ru/data.yml @@ -1,5 +1,19 @@ --- name: Зачем нужны типы данных tips: + - > + [Литерал](https://ru.wikipedia.org/wiki/%D0%9B%D0%B8%D1%82%D0%B5%D1%80%D0%B0%D0%BB_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)) - | [Статья о дробных числах](https://habrahabr.ru/post/112953/) +definitions: + - name: Тип данных + description: >- + множество данных в коде (разновидность информации). Тип определяет, что + можно делать с элементами конкретного множества. Например, целые числа, + рациональные числа, строки — это разные типы данных. + - name: Примитивные типы данных + description: базовые типы, встроенные в сам язык программирования. + - name: Строка (string) + description: > + тип данных, описывающий набор символов (иными словами — текст), например + `"text"`. В Java строки записываются в двойных кавычках. diff --git a/modules/33-data-types/45-explicit-types/ru/README.md b/modules/33-data-types/45-explicit-types/ru/README.md index 7239b97..d558029 100644 --- a/modules/33-data-types/45-explicit-types/ru/README.md +++ b/modules/33-data-types/45-explicit-types/ru/README.md @@ -1,17 +1,62 @@ -До сих пор при определении переменных мы использовали ключевое слово `var`, что может удивить тех, кто имеет какой-то опыт на Java. Обычно определение переменных показывают так: +До сих пор при определении переменных мы использовали ключевое слово `var`. Это может удивить тех, у кого уже есть опыт на Java. Обычно определение переменных показывают так: ```java int x = 3; String greeting = "Hello Hexlet!"; +``` + +Пришло время раскрыть карты. Java — это статически типизированный язык. В таких языках тип переменной фиксируется при ее объявлении и не меняется до конца работы программы. Перед именем переменной указывается ее тип. В примере выше это целое число (*int*) и строка (*String*). + +## Тип указывается явно и не меняется + +В статически типизированном языке у каждой переменной есть тип, и он закреплен. Если переменная объявлена как *int*, то в нее можно положить только целое число: + +```java +int n = 5; +double x = 1.5; +boolean flag = true; +char c = 'A'; +String s = "hi"; +``` + +Попытка положить в переменную значение другого типа приводит к ошибке. Строку нельзя присвоить переменной типа *int*: +```java // Error: incompatible types: java.lang.String cannot be converted to int int ops = "test"; ``` -Пришло время раскрыть карты! Java — это статически типизированный язык. В таких языках тип переменной фиксируется при ее объявлении. В большинстве языков для этого перед именем переменной указывается ее тип — в примере выше это число (int) и строка (String). +## Когда проверяются типы + +Java проверяет типы заранее, еще до запуска программы, на стадии компиляции. Компилятор читает код, сверяет типы значений и операций и отказывается собирать программу, если находит несоответствие. Поэтому ошибку из примера выше мы увидим до того, как программа начнет работать. + +Этим Java отличается от языков с динамической типизацией, где типы проверяются во время работы программы. В таких языках ошибка несоответствия типов всплывает только в момент выполнения подходящей строчки кода. Статическая проверка ловит часть ошибок раньше и помогает не дотащить их до пользователя. + +У явного указания типов есть и второй плюс. Тип рядом с именем переменной работает как подсказка для того, кто читает код. По строчке `int count = 0;` сразу видно, что в переменной хранится целое число. Java берет на себя контроль типов, а код становится понятнее для людей. -Раньше на Java создавали переменные только так, до тех пор пока не появился `var`. Слово `var` – специальное ключевое слово, которое включает механизм **вывода типов**. Вывод типов автоматически определяет тип присваиваемого значения и связывает его с переменной. В примерах выше очевидно, где какой тип, тогда зачем его явно прописывать? +## Когда Java приводит типы сама + +Иногда в одном выражении встречаются значения разных числовых типов. Если сложить целое число и рациональное, Java сама приводит целое к рациональному: + +```java +double result = 1 + 1.5; +System.out.println(result); // => 2.5 +``` + +Целое `1` превращается в `1.0`, и результат получается `2.5`. Так происходит потому, что любое целое число точно представимо как рациональное, и данные не теряются. А вот строку и число Java сама смешивать не станет. Для этого нужно явное преобразование, и мы научимся его делать. + +## Вывод типов и слово var + +Раньше на Java создавали переменные только с явным указанием типа, пока не появилось слово `var`. Это специальное ключевое слово, которое включает механизм **вывода типов**. Вывод типов сам определяет тип присваиваемого значения и связывает его с переменной: + +```java +// Компилятор понимает, что тут целое число +var age = 33; + +// А тут строка +var name = "Tom"; +``` -Вывод типов в Java появился в 2018 году, но в некоторых других язык он существует не один десяток лет. Первый язык с выводом типов называется ML и появился он аж в 1973 году. С тех пор вывод типов был добавлен в Ocaml, Haskell, C#, F#, Kotlin, Scala и множество других языков. +Вывод типов появился в Java в 2018 году, хотя в некоторых других языках он существует не один десяток лет. Первый язык с выводом типов называется ML, и появился он аж в 1973 году. С тех пор вывод типов добавили в OCaml, Haskell, C#, F#, Kotlin, Scala и множество других языков. -Вывод типов и предпочтителен в большинстве ситуаций, однако бывает такое, что выводимый тип нас не устраивает. Тогда мы можем указать тип явно. Подробнее об этом в следующем уроке. +Слово `var` не отменяет статическую типизацию. Тип у переменной все равно есть, его выводит компилятор. После этого тип так же зафиксирован, и положить в такую переменную значение другого типа не получится. Вывод типов предпочтителен в большинстве ситуаций. Бывает, что выводимый тип нас не устраивает, и тогда тип указывают явно. diff --git a/modules/33-data-types/45-explicit-types/ru/data.yml b/modules/33-data-types/45-explicit-types/ru/data.yml index 01a828b..7c2778d 100644 --- a/modules/33-data-types/45-explicit-types/ru/data.yml +++ b/modules/33-data-types/45-explicit-types/ru/data.yml @@ -1,5 +1,16 @@ --- name: Явная типизация tips: + - | + [Типизация](https://ru.wikipedia.org/wiki/Сильная_и_слабая_типизация) - | [Статья о дробных числах](https://habrahabr.ru/post/112953/) +definitions: + - name: Статическая типизация + description: >- + подход, при котором тип переменной фиксируется при ее объявлении и + проверяется заранее, на стадии компиляции, еще до запуска программы. + - name: Вывод типов (type inference) + description: >- + механизм, который сам определяет тип присваиваемого значения и связывает + его с переменной. В Java включается ключевым словом `var`. diff --git a/modules/33-data-types/55-type-casting/ru/README.md b/modules/33-data-types/55-type-casting/ru/README.md index 7240a33..9afa253 100644 --- a/modules/33-data-types/55-type-casting/ru/README.md +++ b/modules/33-data-types/55-type-casting/ru/README.md @@ -1,24 +1,43 @@ -В программировании регулярно встречаются задачи, когда один тип данных нужно преобразовать в другой. Простейший пример – работа с формами на сайтах. +В реальных программах часто возникает ситуация, когда данные одного типа нужно превратить в другой. Один из примеров — работа с формами на сайтах. Данные формы приходят в текстовом виде, даже если по смыслу там число. Чтобы считать с таким значением, его преобразуют в нужный тип. -Данные формы всегда приходят в текстовом виде, даже если значение число. Вот как его можно преобразовать: +## Преобразование строки в число + +Представим, что из формы пришла строка `"345"`, а нам нужно прибавить к этому числу другое. Строку сначала превращают в целое число: ```java -// станет int var number = Integer.parseInt("345"); -System.out.println(number); // => 345 +System.out.println(number + 5); // => 350 ``` -Если нужно конвертировать из примитивного типа в примитивный, то все проще. Достаточно перед значением указать в скобках желаемый тип. В результате значение преобразуется в значение другого типа, указанного в скобках: +Метод `Integer.parseInt` получает строку и возвращает целое число типа *int*. Похожим образом строку превращают в рациональное число с помощью `Double.parseDouble`. + +## Приведение между примитивными типами + +Если преобразовать нужно из одного примитивного типа в другой, хватает указания типа в скобках перед значением. Значение преобразуется в тип, записанный в скобках: ```java var result = (int) 5.1; System.out.println(result); // => 5 ``` -Преобразование типов можно использовать внутри составных выражений: +При приведении рационального числа к целому дробная часть отбрасывается без округления. Поэтому `(int) 5.9` дает `5`. В обратную сторону `(double) 7` дает `7.0`. + +Приведение помогает и при делении. Деление целого на целое в Java дает целое число, а дробная часть теряется: + +```java +System.out.println(7 / 2); // => 3 +System.out.println((double) 7 / 2); // => 3.5 +``` + +В первом случае оба значения целые, поэтому результат целый. Во втором случае делимое приведено к типу *double*, и деление стало рациональным. + +## Приведение внутри составных выражений + +Преобразование типов работает и внутри больших выражений. Дополнительные скобки помогают визуально отделить части выражения друг от друга: ```java -// Дополнительные скобки помогают визуально отделить части выражения друг от друга var result = 10 + ((int) 5.1); System.out.println(result); // => 15 ``` + +Здесь `5.1` приводится к `5`, а затем складывается с `10`. diff --git a/modules/33-data-types/55-type-casting/ru/data.yml b/modules/33-data-types/55-type-casting/ru/data.yml index ba95a7f..605bc43 100644 --- a/modules/33-data-types/55-type-casting/ru/data.yml +++ b/modules/33-data-types/55-type-casting/ru/data.yml @@ -1,2 +1,10 @@ --- name: Явное преобразование типов +tips: + - | + [Типизация](https://ru.wikipedia.org/wiki/Сильная_и_слабая_типизация) +definitions: + - name: Приведение типов (casting) + description: >- + явное преобразование значения одного типа в значение другого типа. + Например, `(int) 5.1` приводит рациональное число к целому.