美文网首页
ruby 方法的调用

ruby 方法的调用

作者: 半岛爱 | 来源:发表于2017-06-23 20:18 被阅读0次

    1、调用的方式

    对象.方法名(参数1,参数2, ... ,参数n)

    以对象开头,中间隔着句点,后面接着是方法名,方法名后面是一排并列的用() 括起来的参数。不同的方法定义的参数个数和顺序也都不一样,调用方法时()可以省略。

    2、带块的方法调用

    带块的方法的语法如下:

    对象.方法名(参数, ...) do |变量1,变量2, ...|

    块内容

    end

    do~end 这部分就是所谓的块。除do ~end 这一形式外,我们也可以用{~}将块改写为其他形式:

    对象.方法名(参数, ...) { |变量1,变量2, ...|

    块内容

    }

    3、运算符形式的方法调用

    Ruby中有些方法看起来很像运算符。四则运算等的二元运算符、-(负号)等的一元运算符、指定数组、散列的元素下标的 等,实际上都是方法。

    obj + arg1

    obj =~ arg1

    -obj

    !obj

    obj[arg1]

    obj[arg1] = arg2

    这些虽然与一般的方法调用的语法有点不一样,但我们可以将obj理解为接收者,将 arg1、arg2 理解为参数,这样一来,它们就又是我们所熟知的方法了。我们可以自由定义这种运算符形式的方法。

    4、方法的分类

    根据接收者种类的不同,Ruby的方法可分为3类:

    实例方法

    类方法

    函数式方法

    4.1实例方法

    实例方法是最常用的方法。假设有一个对象(实例),那么以这个对象为接收者的方法就被称为实例方法

    p "10, 20, 30, 40".split(",")  #=> ["10", "20", "30", "40"]

    p [1, 2, 3, 4].index(2) #=> 1

    p 1000.to_s #=> "1000"

    4.2类方法

    接收者不是对象而是类本身时的方法,我们称之为类方法。

    Array.new  #创建新的数组

    File.open("some_file")  #创建新的文件对象

    Time.now  #创建新的Time对象

    调用类方法时,可以使用::代替.。在Ruby语法中,两者所代表的意思是一样的。

    4.3函数式方法

    没有接收者的方法,我们称之为函数式方法。

    虽说是没有接收者,但并不表示该方法就真的没有可作为接收者的对象,只是在函数式方法这个特殊情况下,可以省略接收者而已。

    print "hello!" #在命令行输出字符串

    sleep(10) #在指定的时间内睡眠,终止程序

    函数式方法的执行结果,不会根据接收者的状态而发生变化。程序在执行print 方法以及 sleep方法的时候,并不需要知道接收者是谁。反过来说,不需要接收者的方法就是函数式方法。

    5、方法的定义

    def 方法名(参数,参数, ...)

    希望执行的处理

    end

    def hello(name)

    puts "Hello, #{name}."

    end

    hello("Ruby")

    参数的默认值,是指在没有指定参数的情况下调用方法时,程序默认使用的值。定义方法时,用参数名= 值这样的写法定义默认值。

    def hello(name="Ruby")

    puts "Hello, #{name}."

    end

    hello() #省略参数的调用

    hello("Newbie") #指定参数的调用

    方法的返回值

    我们可以用return 指定方法的返回值。

    def volume(x, y, z)

    return x * y * z

    end

    p volume(2, 3, 4) #=> 24

    p volume(10, 20, 30) #=> 6000

    可以省略return 语句,这时方法的最后一个表达式的结果就会成为方法的返回值。下面我们再通过求立方体的表面积这个例子,来看看如何省略return 。

    这里, area方法的最后一行的 的结果就是方法的返回值。

    def area(x, y, z)xy = x * y

    yz = y * z

    zx = z * x

    (xy + yz + zx) * 2

    end

    p area(2, 3, 4)

    p area(10, 20, 30) #=> 2200

    方法的返回值,也不一定是程序最后一行的执行结果。例如,在下面的程序中,比较两个值的大小,并返回较大的值。 if语句的结果就是方法的返回值,即a > b的结果为真时,a为返回值;结果为假时,则b为返回值。

    def max(a, b)

    if a > b

    a

    else

    b

    end

    end

    p max(10, 5)

    #=> 10

    因为可以省略,所以有些人就会感觉好像没什么机会用到return,但是有些情况下我们会希望马上终止程序,这时return就派上用场了。用return语句改写的max方法如下所示,大家可以对比一下和之前有什么异同。

    def max(a, b)

    if a > b

    return a

    end

    return b

    end

    #这里的return可以省略

    p max(10, 5) #=> 10

    如果省略return的参数,程序则返回nil。

    定义带块的方法

    首先我们来实现myloop 方法,它与利用块实现循环的loop 方法的功能是一样的。

    def myloop

    while true

    yield

    end

    end

    num = 1

    myloop do

    puts "num is #{num}"

    break if num > 100

    num *= 2

    end

    yield是定义带块的方法时最重要的关键字。调用方法时通过块传进来的处理会在 yield定义的地方执行。

    本例的程序中没有参数,如果yield 部分有参数,程序就会将其当作块变量传到块里。块里面最后的表达式的值既是块的执行结果,同时也可以作为yield的返回值在块的外部使用。

    参数个数不确定的方法

    像下面的例子那样,通过用“变量名”的形式来定义参数个数不确定的方法,Ruby就可以把所有参数封装为数组,供方法内部使用。

    def foo(*args)

    args

    end

    p foo(1, 2, 3) #=> [1, 2, 3]

    至少需要指定一个参数的方法可以像下面这样定义:

    def meth(arg, *agrs)

    [arg, args]

    end

    p meth(1) #=> [1, []]

    p meth(1, 2, 3) #=> [1, [2, 3]]

    所有不确定的参数都被作为数组赋值给变量args。“*变量名”这种形式的参数,只能在方法定义的参数列表中出现一次。只确定首个和最后一个参数名,并省略中间的参数时,可以像下面这样定义

    def a(a, *b, c)

    [a, b, c]

    end

    pa(1,2,3,4,5) #=>[1,[2,3,4],5]

    p a(1, 2) #=> [1, [], 2]

    关键字参数

    在目前为止介绍过的方法定义中,我们都需要定义调用方法时的参数个数以及调用顺序。而使用关键字参数,就可以将参数名与参数值成对地传给方法内部使用。

    def 方法名(参数 参数1的值,参数 参数2的值, ...)

    希望执行的处理

    end

    除了参数名外,使用“参数名:值”这样的形式还可以指定参数的默认值。用关键字参数改写计算立方体表面积的 方法的程序如下所示:

    def area2(x:0, y:0, z:0)

    xy = x * y

    yz = y * z

    zx = z * x

    (xy + yz + zx) * 2

    end

    p area2(x: 2, y: 3, z: 4)

    p area2(z: 4, y: 3, x: 2)

    p area2(x: 2, z: 3)

    为了避免调用方法时因指定了未定义的参数而报错,我们可以使用“**变量名”的形式来 接收未定义的参数。下面这个例子的方法中,除了关键字参数x、y、z外,还定义了**arg参数。参数arg会把参数列表以外的关键字参数以散列对象的形式保存。

    def meth(x: 0, y: 0, z: 0, **args)

    [x, y, z, args]

    end

    p meth(z: 4, y: 3, x: 2) #=> [2, 3, 4, {}]

    p meth(x: 2, z: 3, v: 4, w: 5) #=> [2, 0, 3, {:v=>4, :w=>5}]

    关于方法调用的一些补充

    把数组分解为参数

    将参数传递给方法时,我们也可以先分解数组,然后再将分解后的数组元素作为参数传递给方法。在调用方法时,如果以“*数组”这样的形式指定参数,这时传递给方法的就不是数组本身,而是数组的各元素被按照顺序传递给方法。但需要注意的是,数组的元素个数必须要和方法定义的参数个数一样。

    def foo(a, b, c)

    a+b+c

    end

    p foo(1, 2, 3) #=> 6

    args1 = [2, 3]

    p foo(1, *args1) #=> 6

    args2 = [1, 2, 3]

    p foo(*args2) #=> 6

    把散列作为参数传递

    我们用 这样的形式来表示散列的字面量(literal)。将散列的字面量作为参数传递给方法时可以省略 。

    def foo(arg)

    arg

    end

    p foo({"a"=>1, "b"=>2})#=> {"a"=>1, "b"=>2}

    p foo("a"=>1, "b"=>2)#=> {"a"=>1, "b"=>2}

    p foo(a: 1, b:2)#=> {:a=>1, :b=>2}

    当虽然有多个参数,但只将散列作为最后一个参数传递给方法时,可以使用下面的写法:

    def bar(arg1, arg2)

    [arg1, arg2]

    end

    p bar(100, {"a"=>1, "b"=>2})#=> [100, {"a"=>1, "b"=>2}]

    p bar(100, "a"=>1, "b"=>2)#=> [100, {"a"=>1, "b"=>2}]

    p bar(100, a: 1, b: 2)#=> [100, {:a=>1, :b=>2}]

    相关文章

      网友评论

          本文标题:ruby 方法的调用

          本文链接:https://www.haomeiwen.com/subject/tkzccxtx.html