函数

数字的计算和字符串的显示等,能够进行某种处理的被命名的功能称为函数

函数的使用

函数这一个词语来源于数学,但在程序中使用的函数,实际上更加接近「命令」。 我们一直在使用的 p、print 命令其实也是函数的一种。

学习自定义函数的方法前,让我们像函数那样来使用函数吧。 先介绍生成随机数的 rand 函数。

p rand(100)

这个示例是每次运行都会显示出(0~99)中的任意一个随机数字的程 序。rand 函数是从 0 到指定整数这个不大的范围中随机选取一个数字并返回的函数。 这个「指定的值」就称为参数。 参数通常在函数名称后面的括号 () 内指定。(像之前 print 函数的调用,不产生歧义的话也可以省略括号)上面示例里 100 就是 rand 函数的参数。 参数如不直接指定数值的话,还可以像下面的示例那样使用任意的运算。

x = 10
y = 20
p rand(x + y) # 等同于 p rand(30)

与参数相反,函数将原始数值进行处理后返回的结果数值称为返回值。 也就是说,rand 函数的返回值是在特定范围内的随机数值。 函数的返回值可以像普通数字和变量那样被使用。

p rand(6) + 1

上面示例的意思是 rand 函数的返回值加上 1,并显示其计算结果。rand 函数 在给予的参数为 6 的情况下返回值为 0 到 5 范围内的任意一个数, 所以再加上 1,就像丢骰子一样随机显示一个 1 到 6 范围内的数值。

像 print 和 rand 那样的函数已预先内建于系统中,所以称为内建函数

函数的定义

函数的定义是从 def 开始到 end 结束。 具体的语法如下所示。

def 函数的名称
函数的内容
end

函数名称的命名方法,基本上和局部变量相同。 虽然可以在开头使用大写字母,但不推荐函数命名时使用。 另外,作为函数命名的例外,在名称的最后还可以添加 ? 或 ! 符号。

比如,先前的 rand(6) + 1 处理可以定义为 dice 名称的函数, 我们下面就来进行。这样定义了该函数, 从此以后只要写 dice 就会得到一个 1 到 6 的随机数字。

def dice
return rand(6) + 1
end

p dice # 等同于 p rand(6) + 1

这里的 return 就是结束函数处理的命令。函数可以考虑为 VA 的公共事件, 而 return 就是相当于「中断事件处理」的意思。return 右侧所写的运算, 就是该函数的返回值。函数不在中途中断的话还可以省略 return。

参数

含有参数的函数,如下面示例那样定义。

def abs(x)
if x < 0 # 如果 x 小于 0 的话,
return -x # 结束函数,返回值 -x。
else # 除此之外,
return x # 结束函数,返回值 x。
end # 分歧结束。
end

p abs(-3) # => 3

这个是返回指定参数数值绝对值的函数。这里「指定参数数值」暂时定义为 x。 这个 x 称为形式参数。在函数内部使用有条件分歧,x 小 于 0 时(为负数)返回值 -x,除此之外(为 0 以上的数)返回值 x。 最后一行是指定参数为 -3 的实际情况下使用函数,其结果用 p 函数输出。 与 x 为形式参数相比,这儿的 -3 称为实际参数

顺便讲一下,所谓绝对值是数学上提出的概念,是表示到原点(上述情况 可以认为是 0)距离的数值。-3 也好 +3 也好,原点为 0 的情况下, 每个到 0 的距离都为 3。

含有多个参数的函数也能定义。多个参数要用逗号 ',' 分开来指定。

def sum(x, y)
return x + y # 结束函数,返回值 x + y。
end

p sum(2, 3) # => 5

这个是返回指定参数两个数值之和的函数。当然实际中写成 2 + 3 更快更容易, 一般不会定义这样简单的函数。这只是说明语法的示例。

实际中参数省略括号 () 也能使用。

默认参数

定义函数时就已指定且使用时可以省略的参数称为默认参数。 默认参数是在形式参数后面加上符号 = 来指定的。事先设置好了默认参数, 在使用函数时未指定括号 () 内实际参数数值的情况下,形式参数就会自动代入默认参数数值。

def dice(n = 6)
return rand(n) + 1
end

p dice # 等同于 p dice(6)

上述示例中未指定参数,使用函数时会返回一个 1~6 的随机数字, 然而指定参数的话,就能更改随机数字的最大值。比如, 使用 dice(8) 就会返回一个 1~8 的随机数字。

大部分内置函数都有这样省略参数的功能。

函数的重定义

下面的示例中,hello 名称的函数被重复定义了 2 回。

def hello
return "您好"
end

def hello
return "晚安"
end

p hello # => "晚安"

在 Ruby 中,函数名称重复的话不会出现错误。 这种情况下系统会认定后面定义的函数有效,而先前的定义就无效了。