OxL Справочник OxL
РусскийEnglish

Шаг 2. Функции

Зачем#

Функция — основная единица повторного использования. В OxL сигнатура функции — это её контракт: типы параметров, тип результата и (о чём шаг 8) эффекты описаны в одном месте. Поэтому читать код можно, не заглядывая в тела функций.

Тело функции — выражение: последнее выражение блока и есть результат, return нужен только для раннего выхода. if и match тоже выражения, поэтому тернарного оператора в языке нет — он не нужен.

Пример#

oxl✓ проверяется в CI
fn square(x: i32) -> i32  pure => x * x  // pure — без побочных эффектов

fn greet(name: str, greeting: str = "Hello", loud: bool = false) -> str  pure {
  let text = "{greeting}, {name}"
  if loud { text.upper() } else { text }  // if — выражение; последнее выражение блока — результат
}

// вариадический параметр: внутри функции xs — срез
fn sumAll(...xs: i32) -> i32  pure {
  var total = 0
  for x in xs { total += x }
  total
}

fn apply(f: fn(i32) -> i32, x: i32) -> i32  pure => f(x)

fn main() io {
  print("{square(7)}")
  print(greet("Ann"))
  print(greet("Bob", loud: true))  // именованный аргумент
  print("{sumAll(1, 2, 3, 4)}")
  let k = 10
  let addK = (x: i32) => x + k  // замыкание захватывает k
  print("{apply(addK, 5)} {apply(square, 6)}")
}
Вывод
49
Hello, Ann
HELLO, BOB
10
15 36

Разбор#

  • fn square(x: i32) -> i32 pure => x * x — короткая форма => выражение. Слово pure означает «без побочных эффектов»: такую функцию можно вызвать откуда угодно.
  • greeting: str = "Hello" — значение по умолчанию вычисляется при каждом вызове, где аргумент опущен. Необязательные параметры удобно передавать по имени: greet("Bob", loud: true). Сначала идут позиционные аргументы, потом именованные.
  • ...xs: i32 — вариативный параметр; внутри функции это срез [i32], по которому можно пройти циклом for.
  • (x: i32) => x + k — лямбда. Она захватывает k из окружающего кода. Функцию можно передать как значение: параметр f: fn(i32) -> i32 принимает и лямбду, и обычную функцию square.
  • Сигнатуры функций с pub/pub(api) пишутся полностью; у приватных функций тип результата может быть выведен из => выражения.

Типичная ошибка: неверное число аргументов#

oxl✓ проверяется в CI
fn add(a: i32, b: i32) -> i32 => a + b

fn main() {
  let s = add(1)
}
error
arg-count

Компилятор называет функцию и сообщает, сколько аргументов ожидалось: arg-count. Если параметр должен быть необязательным, дайте ему значение по умолчанию. Имя несуществующего именованного параметра даёт named-arg.

Что запомнить#

  • Результат — последнее выражение; return — для раннего выхода.
  • Значения по умолчанию + именованные аргументы заменяют перегрузку функций.
  • Лямбды и функции взаимозаменяемы там, где ожидается fn(…) -> ….

Дальше: данные: data и enum.

См. также

OxL 1.0.0-beta · Версия документации 1.0.0-beta© OxwaldLink · сгенерировано из Стандарта, исходников std и руководства