вставленное определение (анонимной) функции на языке 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 |
|