Scilab Home page | Wiki | Bug tracker | Forge | Mailing list archives | ATOMS | File exchange
Please login or create an account
Change language to: English - Français - Português - 日本語 -
Справка Scilab >> Функции > deff

deff

вставленное определение (анонимной) функции на языке Scilab

Синтаксис

deff(funcHeadline, funcBody)
deff(definition)
deff("[r1, r2, ...] = myFunc(in1, in2, ...)", funcBody)
deff "r = myFunc(x,y) r = x^2 - y"
deff "r = myFunc(x,y) x^2 - y"
deff("r = @(x,y) x^2 - y")      // в качестве элемента анонимного контейнера

myFunc = deff(funcHeadline, funcBody)
myFunc = deff(definition)
myFunc = deff("[r1, r2, ...] = fakeName(in1, in2, ...)", funcBody)
myFunc = deff("r = fakeName(x,y) r = x^2 - y")
myFunc = deff("r = fakeName(x,y) x^2 - y")
myFunc = deff("r = @(x,y) x^2 - y")

Аргументы

x, y, in1, in2, ...
входные аргументы определяемой функции. Последняя может иметь любое количество входных аргументов, от 0 до любого N.

r, r1, r2, ...
результаты на выходе определяемой функции. Последняя может иметь любое количество результатов на выходе, от 0 до любого M. Все выходные аргументы должны быть явными, то есть, записанными слева от имени функции.

funcHeadline
одиночная строка: заголовок функции, то есть, её первая строчка, указывающая локальное имя функции и списки её входных аргументов с правой стороны и выходных аргументов с левой стороны. Примеры:
  • "myFunction(x,y)" : нет аргументов на выходе
  • "r = myFunction(x,y)" : один аргумент на выходе
  • "[a,b] = myFunction(x,y)" : два аргумента на выходе. И т.д.
Пожалуйста, обратите внимание, что a) ключевое слово function не обязательно указывать. b) запись выходных аргументов, если они есть, на левой части заголовочной строчки является обязательной.

funcBody
вектор текстов, то есть Scilab-инструкций тела функции, в том порядке, в котором они должны быть выполнены. Эти инструкции должны определять и назначать значения всех выходных аргументов. Завершающее ключевое слово "endfunction" не ожидается.

Этот вектор ожидается, когда deff(…) вызывается с двумя входными аргументами.

Одинарные или двойные кавычки внутри инструкций должны дублироваться для защиты.

definition
Отдельный текст или вектор текстов, включая как заголовочную строчку функции, так и тело.
  • Если это вектор, то это эквивалентно definition = [funcHeadline ; funcBody].
  • В противном случае одностроковое определение эквивалентно funcHeadline + " " + strcat(funcBody,"; ").
Пожалуйста, смотрите разделы "Описание" и "Примеры".

myFunc
Публичное имя и идентификатор определяемой функции, неявно возвращаемый в текущее окружение, либо явно присваиваемый переменной на выходе deff(…).

Когда deff(…) вызывается без явных выходных аргументов, но в качестве элемента контейнера или в качестве входного аргумента другой функции, то она неявно присваивается этому элементу или аргументу, который является анонимным. То тогда она является анонимной функцией. Например:

L = list(3, deff("r=noName(x) x.^2+1"), "Hello");. Результат deff(…) присваивается L(2). Тогда L(2)(3.5) // ➜ 13.25.

Описание

deff(…) может использоваться для определения отдельной функции из инструкций Scilab, указанных через матрицу текстов, вместо любого внешнего текстового файла с инструкциями для исполнения, записанными в блок function … endfunction.

Файл исходного Scilab-кода может включать в себя определение нескольких публичных функций. Это не возможно сделать с помощью deff(…): только одну публичную функцию можно определить. Однако, как и в случае с файлом, тело определяемой функции может включать в себя один или несколько блоков function … endfunction, определяющих вложенные приватные функции.

Независимо от синтаксиса deff(…), используемого для обеспечения исходного кода (см. ниже), если он содержит синтаксическую ошибку, то deff(…) выдаст ошибку компиляции и остановит работу.

Указание исходного кода

deff(funcHeadline, funcBody) (2 входа) и deff([funcHeadline ; funcBody]) (единый конкатенированный вход) эквивалентны.

Когда funcBody сделана только из одной (короткой) строки, она может быть приклеена и передана вместе с funcHeadline, как одностроковое определение функции. Примеры:

deff("[a,b] = myFunction(x,y) a = x.^2; b = x-y;")
deff("r = myFunction(x,y) r = (x-y).^2"). Это можно даже упростить до
deff("r = myFunction(x,y) (x-y).^2")
deff("myFunction(x,y) disp(x.^2 - b)")

Когда результат deff(…) присваивается или вводится в любой анонимный контейнер, то оказывается, что псевдоимя fakeName, определённое в funcHeadline не играет роли вообще, и может совсем не использоваться для вызова функции. Это имя может быть тогда заменено символом "@" в funcHeadline для указания, что определяемая функция становится анонимной.

Идентификатор определяемой функции

Идентификатор - это фактическое слово (имя), которое используется для вызова определяемой функции. Следующие три случая представлены для примера.

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

В противном случае, когда deff(…) вызывается с явным выходным аргументом, то его имя становится единственным фактическим идентификатором публичной функции. В результате, имя функции, используемой в исходном коде, нельзя использовать для её вызова. Оно становится псевдоименем. По этой причине в заголовочной строчке может быть использован символ "@" (ставящийся для "анонимок") вместо какого-либо корректного имени функции, определённой в заголовочной строчке. Но это не обязательно.

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

Примеры

Неприсваивающие функции

deff('x = myplus(y,z)', 'x = y+z')
myplus(1,%i)

deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
a = 3;
[u, v] = mymacro(2)
--> deff('x = myplus(y,z)', 'x = y+z')
--> myplus(1,%i)
 ans  =
   1. + i

--> deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
--> a = 3;
--> [u, v] = mymacro(2)
 v  =
   10.

 u  =
   7.

С единственным входным и выходным аргументом:

clear myFunc
source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
deff(source)
myFunc(3, -2)
--> source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
 source  =
  "r = myFunc(x,y)"
  "r = x.*(x-y)"

--> deff(source)
--> myFunc(3, -2)
 ans  =
   15.

Тот же пример с одностроковым определением, которое затем позволяет синтаксис, ориентированный на командную строку (без необязательных скобок deff, но с, по-прежнему, обязательными разделительными кавычками):

clear myFunc
deff "r = myFunc(x,y) r = x.*(x-y)"
myFunc(1:3, -2)
--> deff "r = myFunc(x,y) r = x.*(x-y)"
--> myFunc(1:3, -2)
 ans  =
   3.   8.   15.

Для однострокового прямого определения с единственным выходным аргументом, мы можем даже опустить дубликат "r = " в теле функции:

clear myFunc
deff "r = myFunc(x,y) x.*(x-y)"
myFunc(1:3, -2)
--> deff "r = myFunc(x,y) x.*(x-y)"
--> myFunc(1:3, -2)
 ans  =
   3.   8.   15.

Функция без присваиваемого выходного аргумента: обратите также внимание на использование удвоенных кавычек для защиты их в строке определения:

clear myFunc
deff("myFunc(x, y) messagebox(prettyprint(x.*(x-y), ""html"",""""))")
myFunc([1 2 ; 3 4], -2)
Определяемая функция, присваиваемая реципиенту

Придержимся примеров, похожих на приведённые выше:

clear myFunc actualName
actualName = deff("r = myFunc(x,y) x.*(x-y)")
isdef(["myFunc" "actualName"])
actualName(1:3, -2)
myFunc(1:3, -2)
--> actualName = deff("r = myFunc(x,y) x.*(x-y)")
 actualName  =
[r]=actualName(x,y)

--> isdef(["myFunc" "actualName"])
 ans  =
  F T

--> actualName(1:3, -2)
 ans  =
   3.   8.   15.

--> myFunc(1:3, -2)
Undefined variable: myFunc

Поскольку имя "внутренней" функции является псевдоименем, то мы можем вместо него использовать "@" (символ "@" нельзя использовать в фактических именах функций):

clear actualName
actualName = deff("r = @(x,y) x.*(x-y)");
actualName(1:3, -2)
--> actualName = deff("r = @(x,y) x.*(x-y)");
--> actualName(1:3, -2)
 ans  =
   3.   8.   15.

Теперь напрямую присвоим созданную функцию безымянному реципиенту. Хотя функция становится анонимной, мы, по-прежнему, можем вызывать её:

L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
L(2)(1.1:4, -2.1)
// Мы можем извлекать и устанавливать имя анонимной функции:
Abc = L(2)
Abc(1.1:4, -2.1)
--> L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
--> L(2)(1.1:4, -2.1)
 ans  =
   3.52   8.82   16.12

--> Abc = L(2)
 Abc  =
[r]=Abc(x,y)

--> Abc(1.1:4, -2.1)
 ans  =
   3.52   8.82   16.12

Наконец, давайте используем deff() для прямого определения и передачи функции в качестве входного элемента другой функции:

function r=test(txt, x, theFunc)
    r = x + theFunc(txt)
endfunction

test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
--> test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
 ans  =
   13.7

В этом примере передаваемая функция является анонимной в вызывающем окружении, но присваивается и получает своё имя "theFunct" внутри вызываемой функции.

Смотрите также

  • function — открывает определение функции
  • exec — исполнение файла-сценария
  • getd — загрузка всех функций, определённых в директории
  • genlib — строит библиотеку из набора *.sci-файлов, определяющих функции в указанной директории
  • jdeff — Map a static Java method onto a Scilab macro
  • jcompile — Компилирует код или файл Java

История

ВерсияОписание
6.0.0
  • Входная опция opt="c"|"p"|"n" больше не доступна.
  • Определяемая newfunction теперь имеет тип 13 (вместо 11).
6.1.1
  • Добавлен необязательный выходной аргумент. Могут определяться анонимные функции.
  • Поддерживаются одиночные входные аргументы, конкатенирующие заголовочную строку функции и её тело.
  • Поддерживается синтаксис одиночной строки, вроде deff "r = myFun(x,y) x.^2-y"
  • Поддерживается псевдоимя функции "@".
Scilab Enterprises
Copyright (c) 2011-2017 (Scilab Enterprises)
Copyright (c) 1989-2012 (INRIA)
Copyright (c) 1989-2007 (ENPC)
with contributors
Last updated:
Tue Jul 20 11:21:28 CEST 2021