MENU

Julia学习笔记(4)--函数的定义

• February 25, 2020 • Read: 2438 • Julia语言

函数的定义

Julia语言是一种函数范式的编程语言,自然函数function在Julia中扮演着重要的角色,对于熟悉Matlab的用户来说,科学计算或者数值计算中,往往都是通过构建函数,通过它们之间的相互调用来完成计算任务的,同样Julia中也是如此,而Julia中的函数又有着自己的特殊性质,即具备函数的方法

通常一说到方法,往往会让人联想到Python中对象的方法,这是一种面向对象编程范式的思路,而Julia是一种函数式编程语言,它的方法是针对函数中输入参数的类型来说的。这也是Julia的一个特点,它具有一定意义的静态语言的特性,即可以进行变量类型的申明。

自定义函数

内置的函数通常只能完成最基础的计算任务,大部分我们要实现的计算任务都需要通过自己编写函数来完成。利用关键词function来进行函数的构建,function必须要以end进行结尾。

# 定义一个函数test
function test(a,b,c.....输入参数)
    statement.....
    return 返回值
end

上述是函数test的定义方式,函数名字后面括号内是函数的输入参数,多个参数用逗号隔开;函数的返回值默认是返回最后一个表达式的结果,当然通常需要用关键词return来进行返回值的申明,多个返回值用逗号分隔。

function test_add(a, b)
    c = a + b
    return c
end

定义了一个test_add函数,具有两个返回值,用于计算两个输入参数的和并返回计算的结果。这个函数的定义中,对于输入参数a和b来说并没有指定变量的类型,通常在动态语言中都不需要指定变量类型,在使用中时直接使用即可,这样输入参数既可以是整型也可以是浮点型,也就是适用性更强。而Julia具备变量申明的功能,往往在构建大型程序时,申明类型会减少函数之间相互调用的错误,更加的严谨。

类型申明与函数的方法

类型

之前已经学习了一些常用的变量类型,即整型和浮点数型。Julia中对于变量类型的申明是使用::两个冒号进行的。

在类型被省略时,Julia 的默认行为是允许变量为任何类型。因此,可以编写许多有用的 Julia 函数,而无需显式使用类型。然而,当需要额外的表达力时,很容易逐渐将显式的类型注释引入先前的「无类型」代码中。添加类型注释主要有三个目的:

  • 利用 Julia 强大的多重派发机制
  • 提高代码可读性以
  • 捕获程序错误

::操作符可以读作“是....的实例”,在任何地方都可以用它来断言左侧表达式的值是右侧类型的实例。而当断言在赋值左侧时(即等号左侧时),此时意味着该变量的类型始终是申明的类型,与静态语言(如C语言)完全一致。

(1+2)::Int # 计算结果是Int型

# 左侧进行断言时
function foo()
    x::Int8 = 100
    return x
end

此时调用foo函数得到的结果会是一个Int8类型的值。变量类型的指定一个重要作用就是避免出现性能陷阱,足够简单的量就用相应简单的类型去搞定,避免内存及算力的浪费。需要注意的是,类型申明不能在全局作用域中使用,即REPL中没有常量类型的全局变量,这表示一个变量你可以随意给定值,不论是数值型还是字符型等等。

作为一门动态语言而言,对于某个变量进行类型指定是没有必要,类型的申明往往用于给定函数输入或者输出结果的类型,因为输入参数往往具有实际意义,比如它的值一定就是整数,那么我们自然希望在函数中指定号它的类型,这也是Julia中可以申明类型的意义所在。

function mytest(a::Int8, b::Int16)::Int16
    return a + b
end

"""
调用函数mytest时,必须保证第一个输入参数为Int8型,
第二个参数为Int16,最终这个函数会返回一个Int16型的结果
"""
# 调用方法
mytest(Int8(1), Int16(2))
# 如果直接写mytest(1,2)就会报错
# 因为Julia中默认的整数类型为Int64

方法

方法是建立在类型申明基础上的一个函数操作,Julia中允许对同一个函数进行多次类型申明,比如,第一次时申明输入参数为Int型,然后再次构建这个函数时,函数名保持不变,输入变量的申明为Float型,Julia中不会覆盖以前的函数,每一次的构建都称为方法,都会被绑定到同一个函数上,即一个函数可能会具有多个方法,当一个函数具有多个函数时,在使用时会依据用户输入的参数类型进行匹配,进而自动调用函数不同的方法,这被称为多充分派。多重分派对于数学代码来说特别有用,人工地将运算视为对于其中一个参数的属于程度比其他所有的参数都强的这个概念对于数学代码是几乎没有意义的:x + y 中的加法运算对 x 的属于程度比对 y 更强?一个数学运算符的实现普遍基于它所有的参数的类型。即使跳出数学运算,多重分派是对于结构和组织程序来说也是一个强大而方便的范式。

前面已经定义了函数mytest函数,并且绑定了一个方法,即第一个参数为Int8,第二个为Int16,现在对这个函数再绑定一个方法

function mytest(a::Int16, b::Int16)::Int16
    return a + b
end

mytest(Int16(1), Int16(2))

当输入参数都为Int16时,函数会自动调用第二次绑定的方法来执行。

匿名函数以及Julia风格的函数定义

匿名函数

匿名函数也是函数定义的一种方式,它的语法要比function要简洁的多,通常用于单一语句的函数定义,在Python中通常用lambda关键词来定义,而Julia中采用"->"来完成,具体如下:

x -> x^2 + 2x - 1
# 等价于
function (x)
    return x^2 + 2x - 1
end

注意,Julia是一门专注于科学计算的语言,所以其语法表达会接近于数学表达式,*通常可以省略。

Julia的数学风格的定义方法

数学中函数表示的是一个映射关系,具体表现为一个表达式,Julia中支持将其写为数学形式。

f(x) = x^2 + 2x - 1
f(1)

总体而言,Julia中的函数与Python中的函数定义以及功能在各方面都大同小异,但是多了类型指定与方法这两个概念,其他的像是输入参数的默认值以及返回多个参数都与Python一致。

Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment

2 Comments
  1. 来看看哥哥,然后学习来了@(笑尿)

    1. @亦行你的网站特效做的好多,一进去笔记本风扇嗡嗡地响。。。。@(滑稽)