京香茱莉亚
Single, multiple, compound expressions, anonymous functions and scopes
单个,多个复合表达式,匿名函数和范围
This is part 8 of the Julia Tutorials (a series of tutorials on Julia). If you are not familiar with Julia Control flows, please go through part 7 for better understanding.
这是Julia教程(关于Julia的一系列教程)的第8部分。 如果您不熟悉Julia Control流程 ,请阅读第7部分,以更好地理解。
If you are not familiar with Julia and want to get started with it, feel free to check out the complete series @ —
如果您不熟悉Julia,并想开始使用它,请随时查看完整的系列@-
Note: Use Julia’s REPL to quickly follow along with the codes in this tutorial
注意:使用Julia的REPL可以快速遵循本教程中的代码
Functions are the important building blocks in Julia, a function is simply a block of code used to perform a single/set of tasks. In Julia, functions can be defined in 2 different ways.
函数是Julia中重要的构建块,函数只是用于执行单个/一组任务的代码块。 在Julia中,可以通过2种不同的方式定义函数。
单表达函数 (Single Expression Functions)
These functions are used to define simple tasks/actions.
这些功能用于定义简单的任务/动作。
Syntax:
句法:
functionName() = # code to execute
Example:
例:
Let’s define a function that receives 2 arguments m
and n
and returns their product.
让我们定义一个函数,该函数接收2个参数m
和n
并返回其乘积。
# Function definition
product(m, n) = m * n# Function call
product(5, 2) # Yields value 10
多种表达功能 (Multiple Expression Functions)
These functions are used when blocks of codes are required to be included in the function’s body.
当要求将代码块包含在函数主体中时,将使用这些函数。
Syntax:
句法:
function functionName()
# Blocks of code
....
end
Example:
例:
Let’s create a function to display the results of multiplication and division performed on 2 variables m
and n
让我们创建一个函数来显示对2个变量m
和n
执行的乘法和除法结果
# Function definition
function arithmetic(m, n)
product = m * n
quotient = m / n
println("Product of $m*$n is: $product")
println("Quotient of $m/$n is: $quotient")
end# Function call
arithmetic(10, 2)
Now, before going into next sections, let’s discuss more about arguments and returns.
现在,在进入下一部分之前,让我们讨论更多有关参数和返回值的信息。
ArgumentsArguments are independent items, or variables, that contain data or codes. In Julia, arguments can be specified in 2 ways, positional and named.
参数参数是包含数据或代码的独立项目或变量。 在Julia中,可以通过两种方式指定参数,即位置和命名。
Positional arguments — These are the commonly used type of argument. Positional arguments are specified by their position and can’t called using their name, doing so will result in an error.
位置参数 —这些是参数的常用类型。 位置参数由其位置指定,不能使用其名称来调用,否则将导致错误。
Example:
例:
function position_demo(a, b=10)
print(a, b)
endposition_demo(1)
position_demo(1, 5)
position_demo(1, b=4) # Results in an error
In the above example b
is an optional argument, i.e, if not specified in the function call, it will take the default value assigned (in this case, it is 10
).
在上面的示例中, b
是一个可选参数,即,如果在函数调用中未指定,它将采用默认值(在这种情况下为10
)。
Keyword arguments — These type of arguments can be called only by their names. They are defined after a ;
关键字参数-这些类型的参数只能通过名称来调用。 它们在;
之后定义;
Example:
例:
function name_demo(a, b=10; c, d=5)
print(a, b, c, d)
endname_demo(1,2,c=3) # a -> 1, b -> 2, c -> 3
name_demo(1,2,3) # Results in an error
name_demo(1, c=5, d=2) # a -> 1, b -> 10, c -> 5, d -> 2
From the above examples, you can see that positional arguments can’t be called by name and keyword arguments can’t be called by position.
从以上示例中,您可以看到不能通过名称调用位置参数,也不能通过position调用关键字参数。
Type assertion in argumentsWe can also specify desired types for function arguments if we want our function to work only on some specific types.
参数中的类型断言如果我们希望函数仅在某些特定类型上工作,我们还可以为函数参数指定所需的类型。
Example:
例:
function name_demo(a::Float64, ::Float64)
print(a, b)
end
ReturnsReturn statements are used to terminate the flow of current function and return the flow/value to the calling function. In Julia, return
is optional since the last computed value of the function is returned by default.
返回值 Return语句用于终止当前函数的流,并将流/值返回给调用函数。 在Julia中, return
是可选的,因为默认情况下会返回该函数的最后一个计算值。
Example:
例:
function addition(a, b)
return a + b
endaddition(1,2) # Yields value 3
This is equivalent to:
这等效于:
function addition(a, b)
a + b
endaddition(1,2) # Yields value 3
As you can see from the above examples, both functions return the sum of a & b. Though Julia returns the last computed value in a function by default, it is still a best practice to specify return
statement in your functions.
从上面的示例中可以看到,两个函数都返回a和b的总和。 尽管Julia默认情况下会返回函数中的最后一个计算值,但在函数中指定return
语句仍然是最佳做法。
You can also return multiple values.
您还可以返回多个值。
Example:
例:
function arithmetic(a, b)
return a + b, a - b
endarithmetic(1,2) # Yields tuple (3, -1)
复合表达式 (Compound Expressions)
Compound expressions are used to execute a sequence of functions one by one and return the last computed value. Compound expressions can be created in 2 ways
复合表达式用于逐个执行一系列函数,并返回最后的计算值。 复合表达式可以通过两种方式创建
Using begin/end
使用 begin/end
Example:
例:
square_root = begin
a = 5
a ^= 2
end
Using ;
使用 ;
Example:
例:
square_root = (a=5; a ^= 2)
匿名函数 (Anonymous Functions)
Anonymous functions are functions that are not bound to an identifier. They do not have a defined name and in some programming languages, they are defined using lambda
keyword. In Julia, anonymous functions can be created in 2 ways:
匿名函数是未绑定到标识符的函数。 它们没有定义的名称,在某些编程语言中,它们是使用lambda
关键字定义的。 在Julia中,可以通过两种方式创建匿名函数:
Using Stabby lambda ->
使用Stabby lambda- ->
Example:
例:
map(x -> 2x^3 + x^2 - 2x + 4, [2, 3, 4, 5])
map
is a higher-order function that applies a given function to each element of an iterable, e.g. a list, returning a list of results in the same order.
map
是一个高阶函数,它将给定函数应用于可迭代对象的每个元素(例如列表),并以相同顺序返回结果列表。
In the above example, the expression x -> 2x^3 + x^2 — 2x + 4
is a stabby lambda function.
在上面的示例中,表达式x -> 2x^3 + x^2 — 2x + 4
2-2x x -> 2x^3 + x^2 — 2x + 4
是稳定的lambda函数。
Note: Use of stabby lambda functions are discouraged by the Julia style guidelines since it can make code confusing and hard to unit test.
注意: Julia样式指南不鼓励使用稳定的lambda函数,因为它会使代码混乱并且难以进行单元测试。
Using do
blocks
使用 do
块
Example:
例:
map(["start", "play", "stop", "resume"]) do x if x == "start"
"Starting the movie..."
"Playing the movie..."
elseif x == "resume"
"Resuming the movie..."
elseif x == "stop"
"Stopping the movie..."
else
"Sorry, I'm not allowed to do this!"
end
end
范围 (Scopes)
In part 7 of this tutorial series (Julia Control flows), we came across variable scopes in loops. If you are familiar with other programming languages, you would probably know about scopes. Scopes are simply the extent up to which an entity is accessible in a program, i.e, for entities such as variables, the scope refers to the region/block in a program where the variable can be referenced by it’s name.
在本教程系列的第7部分(Julia Control流程)中,我们在循环中遇到了可变作用域。 如果您熟悉其他编程语言,则可能会了解范围。 作用域只是在程序中可访问实体的程度,即,对于诸如变量之类的实体,作用域是指程序中可以通过其名称引用变量的区域/块。
Julia implements lexical scoping, i.e, scope of an entity is not inherited from it’s caller, but it’s definition. Let’s look at an example to understand what this means
Julia实现了词法作用域,即 实体的作用域不是从其调用者继承的,而是它的定义。 让我们看一个例子来理解这意味着什么
function foo()
println(x)
end
function bar()
x = 20
foo()
end
In the above example, 2 functions namely foo
and bar
are defined. The function foo
is called upon by the function bar
. What do you think will happen, does the value of x
gets printed?
在上面的示例中,定义了两个函数foo
和bar
。 功能bar
调用foo
函数。 您认为会发生什么, x
的值会被打印吗?
As you can see, calling the function, bar
will results in an UndefVarError
because the variable x
is only visible inside bar
. In other words, the assignment of x
is outside the scope of the function foo
.
如您所见,调用函数bar
将导致UndefVarError
因为变量x
仅在bar
内部可见。 换句话说, x
的赋值超出了函数foo
的范围。
If we want to create a variable that can be accessed by any function in the program, we can use global scope.
如果我们要创建一个可由程序中任何函数访问的变量,则可以使用全局作用域。
Global Scope — Variables defined in global scopes can be accessed by all the functions in the program.
全局范围-程序中的所有函数都可以访问在全局范围内定义的变量。
Example:
例:
x = 10function foo()
println(x)
endfunction bar()
x = 20
foo()
end
Since we declared variable x
globally, this won’t result in an error. But what value will get printed upon calling bar
? Will it be 20
or 10
?
由于我们全局声明了变量x
,因此不会导致错误。 但是调用bar
会打印出什么值? 是20
还是10
?
The value 10
gets printed because, the re assignment of the variable x
inside bar
was not visible to foo
. If we want this re assignment to be reflected in foo
as well, then it needs to be done globally,
之所以会打印值10
,是因为foo
不到bar
内部变量x
的重新分配。 如果我们也希望该重新分配也反映在foo
中,则需要在全局范围内完成,
x = 10function foo()
println(x)
endfunction bar()
global x
x = 20
foo()
end
In the above example, the re assignment was done globally, so it was visible to all other functions in the program. Whenever you want to update a variable globally inside a function or loop, first access the variable using the global
keyword and then do the updates.
在上面的示例中,重新分配是全局完成的,因此它对于程序中的所有其他功能都是可见的。 每当您要在函数或循环内全局更新变量时,请首先使用global
关键字访问变量,然后进行更新。
Note: Though global scopes are helpful, they incur performance penalty. So be sure to use global scope only when necessary.
注意:尽管全局范围很有用,但它们会导致性能下降。 因此,请确保仅在必要时使用全局范围。
Next Up — Methods in Julia
下一步— Julia中的方法
翻译自: https://medium.com/swlh/functions-in-julia-34479ebe598e
京香茱莉亚