通过IronRuby和C#学习Ruby[3]

原文地址:http://www.codethinked.com/post/2008/07/24/Learning-Ruby-via-IronRuby-and-C-Part-3.aspx

上一次,我们讨论了构造器,实例方法,参数,在最后我们还稍稍涉及了点块(block)的概念。在今天的讨论中,我们将继续深入类的静态方法,以及更多关于参数的内容。我们还将结束条件以及循环语句的讲解。

首先,让我们很快地回顾下Person类中的静态方法。举一个简单的例子,我们来定义一个方法来返回Person对象的总数。在C# 中,我们的类看上去是这样的:

public class Person
{
    private static int instanceCount = 0;
   
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {           
        this.FirstName = firstName;
        this.LastName = lastName;
        instanceCount++;
    }   

    public static int InstanceCount()
    {
        return instanceCount;
    }
}

正如你所见,我们仅使用一个静态变量instanceCount来追踪实例的创建。因此,我们能够利用这个静态变量来获取实例的个数。在Ruby中,我们将有若干种不同的方法来达到这个目的一种方案是使用“self”来实现,另一种选择是用类名称,比如这里就是"person",来实现。在接下去的例子中,我们将会使用"self"的方法,当然你也可以尝试采用类名的方法:

class Person
    @@instance_count = 0
   
    attr_accessor :first_name
    attr_accessor :last_name
   
    def initialize(first_name, last_name)
        self.first_name = first_name
        self.last_name = last_name
        @@instance_count += 1
    end
   
    def self.instance_count
        return @@instance_count
    end
end

这里,相信你已经发现了在上一篇中我们定义的静态变量,并且进一步的,我们添加了对应的静态函数。很酷不是吗?看起来比C#简单许多了。让我们看一下如何调用吧:

puts Person.instance_count

好了,关于静态函数我们已经谈论了许多,接下来让我很快地向大家介绍Ruby中的函数传递吧。首先我们介绍一下Ruby中的默认参数机制。一直以来我都希望C#能够提供这样的功能,并且我已听过许多关于参数过载的抱怨,但一直以来我都未能真正解决它。如今,我想我找到了有效的方案!在Ruby中,我能在构造器中使用默认参数,示例如下:

def initialize(first_name = "John", last_name = "Doe")
    self.first_name = first_name
    self.last_name = last_name
    @@instance_count += 1
end

棒极了!如今,我能在不传递参数的情况下调用"new"了,就像这样:.

person = Person.new
puts person.first_and_last_name

正如我们预期,终端上将会打印出“John Doe”。为了在C# 中获得相同的效果,我们将定义三个构造函数:

public Person(): this("John", "Doe") { }
public Person(string firstName) : this(firstName, "Doe") { }
public Person(string firstName, string lastName)
{           
    this.FirstName = firstName;
    this.LastName = lastName;
    instanceCount++;
}

不算太糟,不是吗?但默认参数更体贴些

好了,现在让我们谈谈另一个关于参数的问题吧。Ruby中,hash是可做为list参数传递的。但由于我们还未谈过hash,因此先把它搁一边把,我们之后将会再讨论它。

好了,再来我们看一下boolean类型,在C#中,可按此声明: 

bool isValid = false;

而在Ruby中,因为类型是隐式的,我们可以这样做:

is_valid = true

那么,if语句该怎么办呢?C#中,如下例所示:

if (isValid){
    //do something
}

而Ruby 和此很类似:

if (is_valid)
    #do something
end

进一步的,Ruby提供了unless语句:

unless (is_valid)
    #do something
end

显而易见的,unless是if的反向,当且仅当is_valid为false时,unless中的语句才会执行。在C#中,如下:

if (!isValid){
    //do something
}

很有趣吧,不过Ruby远不止这点能耐!Ruby中,我们可以在put语句中加入if和unless,示例如下:

puts "It is valid!" if is_valid

很有趣吧,现在它读起来更像英语句子了,并且它的意思也更明显了。它将会在“is_valid”为真的时候输出"It is valid!" 。同样,我们可以使用unless

puts "It is not valid!" unless is_valid

接下来,我们讨论一下循环的问题。Ruby支持不同类型的循环机制,比如"while", "until", "do..while", "do..until", and "for".  C#中的循环,看上去如此:

for (int i = 1; i <= 10; i++){
    Console.WriteLine(i);
}

Ruby中是这样的:

for number in 1..10
    puts number
end

C#和Ruby在循环处理上最大的差异就在于典型的循环结构永远不会被用到!我并不想使各位困惑,但这就是事实。在Ruby中,每一个对象都有责任来处理自己的循环,因此,这里我们来介绍“each”方法

这看上去类似于C# 中的foreach:

foreach (string name in names){
    Console.WriteLine(name);
}

Ruby的代码如下:

names.each do |name|
    puts name
end

但如果你结合了Ruby优秀的range特性(C#也支持Range)你能这样来处理循环:

(1..10).each do |num|
    puts num
end

我们也可以这么做:

10.times do |num|
    puts num + 1
end

这里我们需要 "+ 1"是因为"times"方法起始于0。但它会执行10次。

好了,今晚我们就讲到这,在下一片中我们将继续讨论数组的相关话题。

原文地址:https://www.cnblogs.com/Leo_wl/p/1803492.html