方法是由对象定义的与该对象相关的操作。在Ruby中,对象的所有操作都被封装成方法。
这个定义比Python好多了,万物皆对象的世界中,理论上应该不存在函数
方法的调用通过.的方式
带块的方法的调用
(2..5).each {|i| puts i}
(2..5).each do |i|
puts i
end
这种方法 调用,被称为带块的方法的调用。
其中的i被称为块变量,在执行块的时候,块变量由方法传到块内部。
运算符形式的方法的调用
+-*/ =~ []等,这些方法有的可以重新定义,有的不能改变默认的定义
方法的分类
可以分为
实例方法
类方法
函数式方法
实例方法,对象能使用实例方法有对象所属的类决定,但同样的方法可能输出形式不一样
类方法,就是接受者是类的方法
可以通过::或者.来调用类方法
>> Array.new => [] >> Array::new => [] >> Time.now => 2020-05-28 11:44:15 +0800 >> Time::now => 2020-05-28 11:44:17 +0800 >> Array["a",1] => ["a", 1] >>
函数式方法
没有接受者的方法,我们称为函数式的方法
不需要接收者的方法就是函数式方法,这个定义很好,这个也就是Python中所谓的函数。
方法的定义 这个跟Python已经比较像了
...
方法的返回值 (跟Python有很大的区别,默认最后一行为返回值)
定义带块的方法,就是Python中的生成器
num is 1 num is 2 num is 4 num is 8 num is 16 shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$ cat myloop.rb def myloop while true do yield end end num = 1 myloop do # 带块的方法,不需要each方法 puts "num is #{num}" break if num > 10 num *= 2 end shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$
7.3.3 参数个数不确定的方法
通过*args接收不定长参数,跟Python一样。
7.3.4 关键字参数 这个跟Python有区别(应该叫默认参数更加合适)
def 方法名 (参数1: 参数1的值,参数2: 参数2的值,...)
希望执行的处理
end
默认参数用参数名:值的方式,Python用参数名=值的方式
0 146 16 shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$ cat area2.rb def area2(x: 0, y: 0, z: 0) xy = x * y yz = y * z zx = z * x (xy + yz + zx) * 2 end p area2 p area2(x: 2, y: 5, z: 9) p area2(x: 2, z: 4) shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$
如果不需要默认值,只需要"参数名:",这样的指定参数名就可以了
24 40 shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$ cat volume.rb def volume(x:, y: 2, z: 4) x * y *z end p volume(x: 2, y: 3) p volume(x: 5) shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$
接收不定长的关键字参数,通过**args, 这个跟Python好像差不多
[3, 3, 4, {}] [2, 0, 0, {:foo=>3, :zoo=>4}] shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$ cat meth.rb def meth(x: 0, y: 0, z: 0, **args) [x, y, z, args] end p meth(z: 4, y: 3, x: 3) p meth(x: 2, foo: 3, zoo: 4) shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$
关键字参数与普通参数搭配使用
def func(a, b: 1, c: 2)
...
end
调用方法 func(1, b: 2, c: 3)
用散列传递参数,只能用冒号形式的,这个比Python方便
0 146 16 52 60 shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$ cat area2.rb def area2(x: 0, y: 0, z: 0) xy = x * y yz = y * z zx = z * x (xy + yz + zx) * 2 end p area2 p area2(x: 2, y: 5, z: 9) p area2(x: 2, z: 4) args1 = {x: 2, y: 3, z:4} args2 = {x: 5, y: 6} p area2(args1) p area2(args2) shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$
方法调用的一些补充
1 数组解包传参
这个通过*解包,跟Python一样
2把散列作为参数传递(作为普通参数传参)
用{~}这样的形式来表示散列,将散列作为参数传递给方法时可以省略{}
{"a"=>1, "b"=>2} {:arg=>3, :var=>5} shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$ cat foo.rb def foo(arg) # 普通参数入参 arg end p foo("a" =>1, "b"=> 2) # 看着有逗号,起始是一个参数 p foo(arg: 3, var: 5) shijianzhongdeMacBook-Pro:chapter_7 shijianzhong$
日常使用中,应该多用关键字参数 变量名:默认参数 这种
Ruby缩进2个空格