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)"
: два аргумента на выходе. И т.д.
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 — script file execution
- getd — загрузка всех функций, определённых в директории
- genlib — строит библиотеку из набора *.sci-файлов, определяющих функции в указанной директории
- jdeff — Map a static Java method onto a Scilab macro
- jcompile — Компилирует код или файл Java
История
Версия | Описание |
6.0.0 |
|
6.1.1 |
|
Report an issue | ||
<< argn | Функции | exec >> |