summaryrefslogtreecommitdiffhomepage
path: root/ru-ru/nim-ru.html.markdown
blob: 91603494ea19db2a992648475e3ae55a034e7a75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
---
language: Nim
filename: learnNim-ru.nim
contributors:
    - ["Jason J. Ayala P.", "http://JasonAyala.com"]
    - ["Dennis Felsing", "http://felsin9.de/nnis/"]
translators:
    - ["Nomadic", "https://github.com/n0madic"]
    - ["dvska", "https://github.com/dvska"]
lang: ru-ru
---

Nim (ранее известный, как Nimrod) — язык программирования со статической
типизацией, поддерживающий процедурный, объектно-ориентированный,
функциональный и обобщённый стили программирования.

Nim эффективный, выразительный и элегантный.

```nim
var                    # Объявление (и присваивание) переменных,
  буква: char = 'n'    # с указанием типа или без
  язык = "N" & "im"
  nLength : int = len(язык)
  boat: float
  правда: bool = false

let              # Используйте let *сразу* для объявления и связывания переменных.
  ноги = 400     # ноги неизменяемый.
  руки = 2_000   # Символ _ игнорируется и удобен для длинных чисел.
  почтиПи = 3.15

const            # Константы вычисляются во время компиляции. Это обеспечивает
  debug = true   # производительность и полезно в выражениях этапа компиляции.
  компилироватьПлохойКод = false

when компилироватьПлохойКод:    # `when` это `if` этапа компиляции.
  ноги = ноги + 1               # Эта ошибка никогда не будет скомпилирована.
  const ввод = readline(stdin)  # Значения констант должны быть известны во
                                # время компиляции.

discard 1 > 2 # Примечание. Компилятор будет жаловаться, если результат
              # выражения не используется. `discard` обходит это.

discard """
Это может использоваться как многострочный комментарий.
Или для не поддающегося синтаксическому анализу, сломанного кода
"""

#
# Структуры данных
#

# Кортежи

var
  дитя: tuple[имя: string, возраст: int]             # Кортежи определяют *как* имя поля
  сегодня: tuple[солнце: string, температура: float] # так *и* порядок полей.

дитя = (имя: "Rudiger", возраст: 2) # Присвоить все сразу литералом ()
сегодня.солнце = "Пасмурно"         # или отдельно по полям.
сегодня.температура = 20.1

# Последовательности

var
  напитки: seq[string]

напитки = @["Вода", "Сок", "Какао"] # @[V1,..,Vn] является литералом
                                    # последовательности

напитки.add("Молоко")

if "Молоко" in напитки:
  echo "У нас тут Молоко и ещё", напитки.len - 1, " напиток(ов)"

let мойНапиток = напитки[2]

#
# Определение типов
#

# Определение собственных типов позволяет компилятору работать на вас.
# Это то, что делает статическую типизацию мощной и полезной.

type
  Имя = string      # Псевдоним типа дает вам новый тип, который равнозначен
  Возраст = int     # старому типу, но более нагляден.
  Человек = tuple[имя: Имя, возраст: Возраст] # Определение структур данных.
  АльтернативныйСинтаксис = tuple
    fieldOne: string
    secondField: int

var
  джон: Человек = (имя: "John B.", возраст: 17)
  новыйВозраст: int = 18 # Было бы лучше использовать Возраст, чем int

джон.возраст = новыйВозраст # Но это все же работает, потому что int и Возраст синонимы.

type
  Нал = distinct int          # `distinct` делает новый тип несовместимым с его
  Описание = distinct string  # базовым типом.

var
  money: Нал = 100.Нал   # `.Нал` преобразует int в наш тип
  описание: Описание  = "Interesting".Описание

when компилироватьПлохойКод:
  джон.возраст  = money       # Error! возраст is of type int and money is Нал
  джон.имя = описание         # Компилятор говорит: "Нельзя!"

#
# Дополнительные типы и структуры данных
#

# Перечисления позволяют типу иметь одно из ограниченного числа значений

type
  Цвет = enum цКрасный, цГолубой, цЗеленый
  Направление = enum  # Альтернативный формат
    нСевер
    нЗапад
    нВосток
    нЮг
var
  напр = нСевер     # `напр` имеет тип Направление, со значением `нСевер`
  точка = цЗеленый  # `точка` имеет тип Цвет, со значением `цЗеленый`

discard нСевер > нВосток  # Перечисления обычно являются "порядковыми" типами

# Поддиапазоны определяют ограниченный допустимый диапазон

type
  Кости = range[1..20]  # 🎲 Допустимым значением являются только int от 1 до 20
var
  мой_бросок: Кости = 13

when компилироватьПлохойКод:
  мой_бросок = 23  # Error!

# Массивы

type
  СчетчикБросков = array[Кости, int]             # Массивы фиксированной длины и
  ИменаНаправлений = array[Направление, string]  # индексируются любым порядковым типом.
  Истины = array[42..44, bool]
var
  счетчик: СчетчикБросков
  направления: ИменаНаправлений
  возможны: Истины

возможны = [false, false, false]  # Массивы создаются литералом [V1,..,Vn]
возможны[42] = true

направления[нСевер] = "ОО. Великий белый Север!"
направления[нЗапад] = "Нет, не иди туда."

мой_бросок = 13
счетчик[мой_бросок] += 1
счетчик[мой_бросок] += 1

var ещеМассив = ["Идекс по умолчанию", "начинается с", "0"]

# Доступны другие структуры данных, в том числе таблицы, множества,
# списки, очереди и crit-bit деревья.
# http://nim-lang.org/docs/lib.html#collections-and-algorithms (EN)

#
# IO и поток управления выполнением
#

# `case`, `readLine()`

echo "Читали какие-нибудь хорошие книги в последнее время?"

case readLine(stdin)
of "нет", "Нет":
  echo "Пойдите в свою местную библиотеку."
of "да", "Да":
  echo "Тогда продолжим"
else:
  echo "Здорово!"

# `while`, `if`, `continue`, `break`

import strutils as str  # http://nim-lang.org/docs/strutils.html (EN)
echo "Я загадало число между 41 и 43. Отгадай!"
let число: int = 42
var
  ввод_догадка: string
  догадка: int

while догадка != число:
  ввод_догадка = readLine(stdin)

  if ввод_догадка == "": continue  # Пропустить эту итерацию
  
  догадка = str.parseInt(ввод_догадка)

  if догадка == 1001:
    echo("AAAAAAGGG!")
    break
  elif догадка > число:
    echo("Неа. Слишком большое.")
  elif догадка < число:
    echo(догадка, " это слишком мало")
  else:
    echo("Точнооооо!")

#
# Итерации (циклы)
#

for i, элем in ["Да", "Нет", "Может быть"]:  # Или просто `for элем in`
  echo(элем, " по индексу: ", i)

for ключ, значение in items(@[(человек: "You", сила: 100), (человек: "Me", сила: 9000)]):
  echo значение

let мояСтрока = """
<пример>
`строки` для
тренировки
""" # Многострочная "сырая" строка

for строка in splitLines(мояСтрока):
  echo(строка)

for i, симв in мояСтрока:     # Индекс и символ. Или `for j in` только для символов
  if i mod 2 == 0: continue   # Компактная форма `if`
  elif симв == 'X': break
  else: echo(симв)

#
# Процедуры
#

type Ответ = enum оДа, оНет

proc спрос(вопрос: string): Ответ =
  echo(вопрос, " (д/н)")
  while true:
    case readLine(stdin)
    of "д", "Д", "да", "Да":
      return Ответ.оДа  # Перечисления могут быть квалифицированы
    of "н", "Н", "нет", "Нет":
      return Ответ.оНет
    else: echo("Поточнее, да или нет")

proc добавьСахар(колво: int = 2) =   # Значение по умолчанию 2, ничего не возвращает
  assert(колво > 0 and колво < 9000, "Диабет ☠")
  for a in 1..колво:
    echo(a, " кубик...")

case спрос("Сахарку?")
of оДа:
  добавьСахар(3)
of оНет:
  echo "Ну немнооожко!"
  добавьСахар()
# Здесь нет необходимости в `else`. Возможны только `да` и `нет`.

#
# FFI (интерфейс внешних функций)
#

# Так как Nim компилируется в C, то FFI делается очень просто:

proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.}

let cmp = strcmp("C?", "Легко!")
```

Кроме того, Nim выделяется среди себе подобных метапрограммированием,
производительностью, функциями этапа компиляции.

## Дальнейшее чтение (EN)

* [Домашняя страница](http://nim-lang.org)
* [Скачать](http://nim-lang.org/download.html)
* [Сообщество](http://nim-lang.org/community.html)
* [FAQ](http://nim-lang.org/question.html)
* [Документация](http://nim-lang.org/documentation.html)
* [Руководство](http://nim-lang.org/docs/manual.html)
* [Стандартная библиотека](http://nim-lang.org/docs/lib.html)
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nim)