• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

[译林系列--Ruby]通过IronRuby和C#学习Ruby[2]

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

声明:文章版权归原作者所有,转贴请标明原出处及本文地址,原文地址:http://www.codethinked.com/post/2008/07/21/Learning-Ruby-via-IronRuby-and-C-Part-2.aspx

上一次我们讨论了与变量有关的话题,涉及了全局变量,本地变量,以及实例变量和静态变量。在这次的文章中,我们将继续深入讨论ruby的类以及开始定义方法和解决参数传递。

但在开始前,我还是要先简单介绍一下输出命令,这可以使你在之后的学习中更为顺畅。在C#中输出语句为:

Console.WriteLine("My test value");

但在Ruby中:

puts "My test value"

很简单哈~现在你可以在终端输出你要的结果了,那么下面开始我们今天的学习

首先,让我们先以C#为例创建一个带构造器和方法的类:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

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

    public string FirstAndLastName()
    {
        return String.Format("{0} {1}", FirstName, LastName);
    }
}

这里你应该注意到Person类有两个属性并且它们将在构造器里完成初始化。而后我们构造了一个方法,其将使用String.Format来返回first name 和 last name。那么Ruby呢?下面你可能就会对Ruby的简单而感到惊讶了~

class Person
    attr_accessor :first_name
    attr_accessor :last_name
   
    def initialize(first_name, last_name)
        self.first_name = first_name
        self.last_name = last_name
    end
   
    def first_and_last_name
        "#{@first_name} #{@last_name}"
    end
end

事实上,在Ruby中我们用arrtibute accessors来代替C# 中的properties.而后又特别创建了一个特殊的函数“initialize",它相当与一个构造器。在Ruby中我们调用此函数来初始化一个新的类实例,虽然在之后我们会介绍到你实际上并没有必要显示的调用它。接下来,我们介绍一下"first_and_last_name”函数,它将返回一个由first name和last name连接的串。注意,这里我们并没有定义它的返回类型,这是因为Ruby中所有变量都返回一个值而已,不论它是NULL或者是一个有效值。再者你会发现我们根本没有写返回语句,这是因为Ruby中将每一个语句都视作一个返回语句。最后一点,我们在string中直接使用了变量,这是Ruby的语法糖提供的便捷。

在C#中使用这个类会用到new运算符,例如: 

var person = new Person("Ted", "Smith");

而在Ruby中却是new函数:

person = Person.new("Ted", "Smith")

另一个C# 中有用的关键字是“params”,他用来向函数传递变量:

public string Concat(params string[] items)
{
    string result = "";
    foreach (string item in items)
    {
        result += item;
    }
    return result;
}

在Ruby中我们用“*”来完成同样的功能

def concat(*items)
    result = ""
    items.each do |item|
        result += item
    end
    result
end

实质上,Ruby的函数完成了同样的功能,并且其更易读。在C# 版本的示例中,我们用到了foreach语句来循环处理数组。而在Ruby中,我们利用each函数来处理每一个元素。Each函数可能看上去并不像一个函数,(译者著:你可以看到each函数并没有用到圆括号),但实质上,这是因为圆括号在Ruby中一般是可选的。

因此,如果圆括号可以省略,我们可以修改我们之前创建person类的例子如下:

person = Person.new "Ted", "Smith"

这样写,一点问题都没有,你完全可以这样做。但我为什么说这是“一般可选”的呢?这是因为,在有的情况下,例如你内嵌某个函数在语句中,如果省略了圆括号会导致二义性。比如:

person.concat(person.first_and_last_name, "test")

这时如果我们去掉括号:

person.concat person.first_and_last_name "test"

事实上,此时Ruby会试图将test作为person.first_and_last_name的参数,而实质上它是没有函数的,这就造成了一个错误的发生。因此,圆括号只是可选得,那么逗号呢,它是否也是可选的?让我们看个例子

person = Person.new "Ted" "Smith"

哈,如果我们试图这么做就会受到一个错误报告,它指明我们没有能够给person.new提供所需足够参数。那么它认为我们提供了几个参数呢?答案是一个,即“Ted"。那么参数传递是按数组形式传的吗?不是。事实上在Ruby中,"+"符号在字符串中是可选的,这就意味着,连接字符串可以有很多种方案,但我仍坚持使用+运算符。

正如我们先前提到的each函数,它的参数是什么呢?实际上,在"do"和"end"之间的内容就是它的参数。在Ruby中,这被称为一个block。作为C# 程序员,这个例子或许能让你更深刻体会:

items.each { |item| result += item }

把这作为一个action delegate,并使拓展的函数定义看上去像这样:

public void Each<T>(this IEnumerable<T> list, Action<T> func)
{
    foreach (T item in list)
    {
        func(item);
    }
}

现在我们可以在我们的C# 代码中调用它了

items.Each(delegate(string item) { result += item; });

当然我们也可以使用Aggregate function (also called Fold) 并且 Lambda syntax 能使它看起来更相似些。但我不想让你对block和lambda产生过多的困惑 ,因为他们根本不是一回事。不过不必担心,Ruby也有 lambdas!

好了,今晚就说到这。在下一节里,我们将会讨论控制结构并且再深入讨论block,他们都是十分重要的概念!

我希望这篇文章对你的学习有所帮助~


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap