вставленное определение (анонимной) функции на языке 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")
"myFunction(x,y)" : нет аргументов на выходе"r = myFunction(x,y)" : один аргумент на выходе"[a,b] = myFunction(x,y)" : два аргумента
на выходе. И т.д.function
не обязательно указывать. b) запись выходных аргументов, если они есть, на левой
части заголовочной строчки является обязательной.
deff(…) вызывается
с двумя входными аргументами.
![]() | Одинарные или двойные кавычки внутри инструкций должны
дублироваться для защиты. |
definition = [funcHeadline ; funcBody].funcHeadline + " " + strcat(funcBody,"; ").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" внутри вызываемой функции.
| Version | Description |
| 6.0.0 |
|
| 6.1.1 |
|