zoukankan      html  css  js  c++  java
  • 通过IronRuby和C#学习Ruby[2]

    声明:文章版权归原作者所有,转贴请标明原出处及本文地址,原文地址: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,他们都是十分重要的概念!

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

  • 相关阅读:
    20182311 2019-2020-1 《数据结构与面向对象程序设计》实验一报告
    20182311 2019-2020-1 《数据结构与面向对象程序设计》第1周学习总结
    20182320 2019-2020-1 《数据结构与面向对象程序设计》第2-3周学习总结
    20182320 2019-2020-1 《数据结构与面向对象程序设计》实验1报告
    预备作业
    mysql-sysbench编译安装过程问题
    mysql报错-ERROR 2002
    oracle中的root权限问题
    linux物理内存和虚拟内存
    shell-linux普通用户自动登录root脚本
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1803491.html
Copyright © 2011-2022 走看看