2013-03-27 76 views
7

我是Scala的新手,并且听说很多Scala中的所有对象。我没有得到的是“一切都是对象”的优点是什么?如果一切都不是对象,我不能做什么?欢迎举例。谢谢Scala中的所有对象

+1

红宝石在这方面很常见的斯卡拉http://stackoverflow.com/questions/10158791/java-and-ruby-everything-is-an-object-in-oo – 2013-03-27 21:14:34

+2

有人谁知道斯卡拉应该写函数对象的有用的答案了。 – Thomas 2013-03-27 22:06:53

回答

4

将“一切”作为对象的好处是,抽象中断的情况要少得多。

例如,方法不是Java中的对象。所以,如果我有两个字符串,我可以

String s1 = "one"; 
String s2 = "two"; 
static String caps(String s) { return s.toUpperCase(); } 
caps(s1); // Works 
caps(s2); // Also works 

所以我们已经在做一些大写操作中抽象出来的字符串身份。但是,如果我们想要抽象出操作的身份 - 也就是说,我们将东西转换为一个返回另一个字符串的字符串,但是我们想要抽象出细节是什么?现在我们被卡住了,因为方法不是Java中的对象。

在斯卡拉,方法可以转换为功能,这是对象。例如:

def stringop(s: String, f: String => String) = if (s.length > 0) f(s) else s 
stringop(s1, _.toUpperCase) 
stringop(s2, _.toLowerCase) 

现在我们已经抽象出了对非空字符串进行字符串转换的想法。

而且我们可以制定操​​作列表并将它们传递给它们,如果这是我们需要做的。还有其他一些不太必要的情况(对象与类,基元与非类,值类等),但最大的一个是折叠方法和对象之间的区别,以便传递和抽象功能只是就像传递和抽象数据一样简单。

3

好处是,你没有不同的操作符遵循你的语言中的不同规则。例如,在Java中执行涉及对象的操作时,可以使用调用代码的技术(静态对象仍使用dot name技术,但有时会推断出this objectstatic object),而内置项目(而非对象)使用不同的方法,即内置操作员操作。

Number one = Integer.valueOf(1); 
Number two = Integer.valueOf(2); 
Number three = one.plus(two); // if only such methods existed. 

int one = 1; 
int two = 2; 
int three = one + two; 

的主要区别是,dot name技术受到polymorphisim,运算符重载,方法隐藏,和所有的好东西,你可以用Java对象做。 +技术是预定义的,并且完全不灵活。

Scala的由基本上处理它作为一个dot name操作者,并且限定到对象方法这样运算符的强一个一对一映射绕开+方法的不灵活性。因此,在Scala中一切都是对象意味着一切是一个对象,所以

5 + 7 

结果在两个对象被创建的动作(5对象和7对象)5的加方法使用参数7调用对象(如果我的scala内存正确地为我服务),并返回一个“12”对象作为5 + 7操作的值。

这一切都是一个对象在函数式编程环境中有很多好处,例如,代码块现在也是对象,使得可以将代码块(不带名称)作为参数来回传递仍然受到严格的类型检查的约束(代码块仅返回LongString的子类或其他)。

当它归结为它时,它使得某些类型的解决方案非常容易实现,并且通常由于无需处理“进入基元,操纵,移出原语”编组代码而减少低效率。

+0

这有很多事情要做与允许任意的符号字符为它做方法名一切都是一个对象。其实,原语是出于性能的考虑_not_正是对象,尽管斯卡拉在掩盖它的拳击方面做得非常非常好(只有在必要时才进行拳击)。 – 2013-03-27 22:21:28

+0

Ho它所做的是一种技巧,观点是“一切都是一个客体”所促成的东西。就像编译Java不是汇编指令一样,即使实现技术将它们转换为编译汇编指令_(又名JIT)。 – 2013-03-28 13:08:28

+0

尽管如此,爪哇不能定义'+'方法_on anything_,而它可以在对象定义一个'plus'方法。它是符号中允许的标识符,而不是一切都是对象,这使得Scala在这里不同。 – 2013-03-28 13:33:33

3

在我看来,一个特定的优点(自从您要求提供示例)是Java中的基本类型(int, boolean ...),Scala中的对象可以通过隐式转换添加功能。例如,如果你想添加一个toRoman方法整型,你可以写像一个隐含的类:

val romanFive = 5.toRoman // V 

此:

implicit class RomanInt(i:Int){ 
    def toRoman = //some algorithm to convert i to a Roman representation 
} 

然后,你可以从任何Int文字像调用此方法你可以'皮条客'的基本类型,以适应他们的需求

+0

这与“Int”是否为对象,或者是否可以创建从基元到类的隐式转换一样。 – 2013-03-27 22:22:32

2

除了其他人提出的观点,我一直强调统一处理所有的价值在斯卡拉是部分幻想。大多数情况下,这是一个非常受欢迎的错觉。 Scala非常聪明,可以尽可能多地使用真正的JVM原语,并且只需要尽可能多地执行自动转换(通常称为装箱和拆箱)。

但是,如果自动装箱和拆箱的应用程序的动态模式非常高,则可能会产生与其相关的不良成本(内存和CPU)。这可以通过使用专门化来部分缓解,当特定类型参数是(程序员指定的)基元类型时,它创建特殊版本的泛型类。这样可以避免装箱和取消装箱,但需要在正在运行的应用程序中使用更多.class文件。

0

并非所有东西都是Scala中的一个对象,不过更多的东西是Scala中的对象而不是Java中的对象。

对象的优点是它们是状态袋,也有一些行为加上它们。随着多态性的加入,对象为您提供了更改隐式行为和状态的方法。对于诗歌来说,让我们来看一些例子。

if语句不是scala或java中的对象。如果是这样,你可以继承它的属性,在它的位置注入另一个依赖关系,并在你的代码使用if语句时使用它来做一些事情,例如登录到文件。这不是神奇吗?它会在某些情况下帮助你调试东西,而在其他情况下,它会让你的头发变白,然后你发现由某人覆盖if的行为引起的错误。

访问一个无客观的,陈述的世界:想象你最喜欢的OOP编程语言。想想它提供的标准库。那里有很多课程,对吧?他们提供定制的方式,对吗?他们采用其他对象的参数,他们创建其他对象。您可以自定义所有这些。你有多态性。现在想象一下,所有的标准库都只是关键字。你几乎无法自定义,因为你不能覆盖关键字。你会被语言设计者决定实施的任何情况困住,而且你无法定制任何东西。这种语言存在,你很了解它们,它们是类续集的语言。你可以勉强创建函数存在,但为了定制SELECT语句的行为,语言的新版本有出现,其中包括最需要的功能。这将是一个极端的世界,你只能通过向语言设计师询问新功能来编程(这可能不会得到,因为其他人更重要的是需要一些功能与你想要的不兼容)

总之,并非所有东西都是scala中的对象:类,表达式,关键字和包确实不是。但是更多的东西,比如功能。 什么是恕我直言,拇指的一个很好的规则是,更多的对象等于更大的灵活性

附:在Python例如,更万物皆对象(如类本身,对于packages类似的概念(即Python模块和包)。你会看到那里,魔法是容易做到,而且会带来好的和糟糕的后果