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 — исполнение файла-сценария
- 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 >> |